Spring 事务
文章目录
- 1. 分析
- 2. 编码
- 2.1 确认切面
- 2.2 编写通知
- 2.3 组装切面
- 3. SpringBoot事务控制
1. 分析
Spring 是通过aop的方式进行开发的,如果你对aop不太了解,可以看 :http://t.csdn.cn/4QfPi
aop编程分为三步 :确认连接点、编写通知、组装切面
1、连接点 :在需要加事务的方法/类上加上 @Transactional
注解。
2、通知 :实现 MethodIntercepter 接口 ,事务操作不就是在开始操作之前开启事务,完成之后提交事务,出现异常回滚事务吗?,开启、提交、回滚这些操作又需要用到 Connection,所以我们需要先注入 Connection。
public class MyAdvice implements MethodInterceptor {
@Autowired
private Connection connection;
@Override
public Object invoke(MethodInvocation var1) throws Throwable {
Object object = null;
try {
connection.setAutoCommit(false);
object = var1.proceed();
connection.commit();
} catch(Exception e) {
connection.rollback();
}
return object;
}
}
但是我们想到的,Spring 也能想到,所以 Spring给我们提供了一个类 :DataSourceTransactionManager
在开发中,我们不需要自己写通知类了,只需要编写配置文件(😒还不如让我写代码),Spring就可以帮我们完成事务操作。
DataSourceTransactionManager
这个类使用的也是 conncetion 进行事务操作,但是connection连接对象直接从连接池中取,所以使用它的前提是配置了连接池DataSource。(我们使用Mybatis肯定会配置这个,所以一般不单独配置)
3、切面 :组装切面使用<tx:annotition-driven transaction-manager=“”>标签完成。这里并没有配置切入点 + 通知,因为是注解操作,所以使用的标签是annotation-driven,Spring会自动扫描加了@Transactional 注解的类/方法。
2. 编码
2.1 确认切面
在类/方法上加上 @Transactional 注解
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
public void add() {
userMapper.addUser();
}
public void delete() {
userMapper.deleteUser();
}
public void update() {
userMapper.updateUser();
}
}
2.2 编写通知
刚才已经说了,Spring 的事务由DataSourceTransactionManager
完成,它又需要连接池获取连接对象,所以要进行依赖注入,将连接池注入,以便Spring使用。
Spring为我们写了通知,我们只需要将连接池注入即可。
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3309/test?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
2.3 组装切面
<tx:annotition-driven transaction-manager="transactionManager"></tx:annotition-driven>
这个标签还有一个属性 :proxy-target-class,值为true/false。
aop的本质是动态代理,事务也是,这个属性就是指定Spring通过哪种方式帮我们创建动态代理对象。
true :Cglib动态代理
false:JDK动态代理
3. SpringBoot事务控制
在SpringBoot中,事务控制变得更为简单,只需要加两个注解,无需其他配置:
- 在启动类上加上
@EnableTransactionManagement
注解
@SpringBootApplication
// 1.在启动类上加:
@EnableTransactionManagement
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
- 在需要开启事务的地方加上
@Transactional
注解
// 加在类上时,默认所有方法使用事务。
@Transactional
public class xxx {
public void add() {
}
}