目录
事务的传播途径
Required 默认的,如果不存在一个事务,则创建新的,如果已经存在,则加入。
例如
@Transactional(propagation = Propagation.REQUIRED)
public void transfer(){
update();
}
@Transactional(propagation = Propagation.REQUIRED)
public void update(){
}
如果update回滚,则transfer也会回滚,当然如果transfer回滚,则update也回滚。
Required_new
不管怎么样都会创建一个新的事务,也就是说update回滚,不会导致transfer回滚。
如果transfer回滚,则update也不会回滚。
NESTED
如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则创建新的。
update回滚,不会导致transfer回滚。如果transfer回滚,则update会回滚。
MANDATORY
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
SUPPORTS
如果当前存在事务,则加入该事务;如果当前没有事务,就以非事务的方式运行。
@Transactional(propagation = Propagation.REQUIRED)
public void transfer(){
update();
}
@Transactional(propagation = Propagation.SUPPORTS)
public void update(){
}
NOT_SUPPORTED
以非事务方式运行,如果当前存在事务,则把当前事务挂起。
NEVER
以非事务方式运行,如果当前存在事务,则抛出异常
还可以在注解中加表示发生那些异常会回滚
@Transactional(rollbackFor = Exception.class)
// 指定一个某个异常不回滚
@Transactional(noRollbackFor = CustomException.class)
spring事务隔离级别
TransactionDefinition.ISOLATION_DEFAULT
:使用后端数据库默认的隔离级别,MySQL 默认采用的 REPEATABLE_READ
隔离级别 Oracle 默认采用的 READ_COMMITTED
隔离级别.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED
:最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
TransactionDefinition.ISOLATION_READ_COMMITTED
: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
TransactionDefinition.ISOLATION_REPEATABLE_READ
: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
TransactionDefinition.ISOLATION_SERIALIZABLE
: 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
spring事物失效的情况
- 将方法声明不是public。
- 在方法中将异常捕获了。
- 这个类没有交给spring管理。
- 类自身调用事物方法,或者直接new 一个类调用了这个方法。
- 底层数据库必须支持事务,例如mysql的innodb支持事物(undo log),而myisam不支持。