1.Spring操作事务方式
一般有三类事务管理的方法:
- 使用JDBC的事务管理: 使用DataSource,从数据源中获取connection,通过con的api进行CRUD,手动的进行commit或者rollback。
- spring提供的编程式的事务管理 通过编程代码在业务逻辑时需要时自行实现,粒度更小;
- 使用spring的声明式事务处理。 通过注解或XML配置实现;
2.事务管理器PlatformTransactionManager
事务管理器PlatformTransactionManager为顶级接口。通用的事务处理流程是由抽象事务管理器AbstractPlatformTransactionManager来提供的,而具体的底层事务处理实现,由PlatformTransactionManager的具体实现类来实现,如DataSourceTransactionManager 、JtaTransactionManager和 HibernateTransactionManager等。
3.JDBC的事务管理
Connection connection = dataSource.getConnection();
try {
connection.setAutoCommit(false);
appointmentService.createAppointment(appt);
connection.commit();
}catch (Exception x){
try {
connection.rollback();
}catch (Exception e){
}
}finally {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
4.编程式事务
依赖:
<!--mybatis-spring-boot-starter依赖包中包含了spring-boot-starter-jdbc的依赖,spring-boot-starter-jdbc中包含
DataSourceTransactionManager事务管理器以及自动注入配置类DataSourceTransactionManagerAutoConfiguration。-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
使用事务模板类 TransactionTemplate
@Autowired
private TransactionTemplate transactionTemplate;
@Override
public void create(){
//
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
orderItemsService.saveBatch(corderItems);
procedureService.costFlowApprove(costFlowApproval);
}
});
}
5.声明式事务
5.1 开启事务两种方法:
5.1 .1 启动类使用注解@EnableTransactionManagement
会自动注入PlatformTransactionManager接口的实现类。
5.1 .2 Bean注入使用事务管理器
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
注解@Bean 将被优先加载,框架不会重新实例化其他的 PlatformTransactionManager 实现类。
5.2 设置多个事务管理器
@Bean(name = "transactionManager1")
public PlatformTransactionManager transactionManager(@Qualifier("dataSource1") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "transactionManager2")
public PlatformTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
使用value/transactionManager 具体指定使用哪个事务管理器
@Transactional(value=""transactionManager1")")
假如存在多个PlatformTransactionManager实例,并且没有实现接口TransactionManagementConfigurer指定默认值。
使用注解@Transactional时,就必须要用value指定使用那个事务。如果不指定,会抛出异常。
如果系统需要提供默认事务管理,需要实现接口 TransactionManagementConfigurer 指定。
如果在业务中必须要明确指定@Transactional的value值,为了避免不必要的问题。不建议实现接口TransactionManagementConfigurer,这样会明确抛出异常,就不会忘记主动指定。
5.3 @Transactional注解相关属性
value和transactionManager属性
配置文件中有多个事务管理器 , 可以用该属性指定选择哪个事务管理器。
propagation属性事务的传播行为 默认为:Propagation.REQUIRED
共有七个传播行为:
REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
当前没有事务,就新建一个事务。如果已经存在一个事务中,加入到这个事务中
SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
当前存在事务,加入该事务。如果当前不存在事务,就以非事务方式执行。
MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
使用当前的事务,如果当前没有事务,抛出异常。
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
新建事务,如果当前存在事务,把当前事务挂起(相当于停止)。
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
以非事务方式执行,如果当前存在事务,就把当前事务挂起。
NEVER(TransactionDefinition.PROPAGATION_NEVER),
以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED(TransactionDefinition.PROPAGATION_NESTED);
支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。与PROPAGATION_REQUIRED类似的操作。
isolation属性 事务的隔离级别,默认值为 DEFAULT
DEFAULT(TransactionDefinition.ISOLATION_DEFAULT) 根据数据库默认的隔离级别配置
数据库不同配置不同。mysql默认为可重复读REPEATABLE_READ
READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED) 读取未提交
READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED) 读取已提交
REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ) 可重复读
SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE) 串行化
timeout属性
设置事务的超时秒数,默认值为-1表示永不超时。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly属性
设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。
@Transactional(readOnly=true)
rollbackFor属性
设置需要进行回滚的异常类型,当方法中抛出指定异常类型中的异常时,事务回滚。
指定一个类:@Transactional(rollbackFor=RuntimeException.class)
指定多个类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
rollbackForClassName属性
设置需要进行回滚的异常类名称,当方法中抛出指定异常类名称中的异常时,事务回滚。
指定一个名称:@Transactional(rollbackForClassName=“RuntimeException”)
指定多个名称:@Transactional(rollbackForClassName={“RuntimeException”,“Exception”})
noRollbackFor属性
设置不需要进行回滚的异常类型,当方法中抛出指定异常类型中的异常时,不进行事务回滚。
指定一个名称:@Transactional(noRollbackFor=RuntimeException.class)
指定多个名称:@Transactional(noRollbackFor={RuntimeException.class,Exception.class})
noRollbackForClassName属性
设置不需要进行回滚的异常类名称,当方法中抛出指定异常名称中的异常时,不进行事务回滚。
指定一个名称:@Transactional(noRollbackForClassName=“RuntimeException”)
指定多个名称:@Transactional(noRollbackForClassName={“RuntimeException”,“Exception”})
5.4 使用@Transactional注意
5.4.1 @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能。
5.4.2 有事务方法,遇到RuntiomeException时会回滚,遇到受检查的异常不会回滚,要想所有异常都回滚,要加上@Transactional(rollbackFor = Exception.class)