事务是逻辑上的一组操作,要么都执行,要么不执行。
事务能否生效数据库引擎是否支持事务的关键。比如常用的mysql数据默认的使用支持事务innodb引擎。但是,数据引擎变为mysiam,那么程序也就不再支持事务了。
事务特性(ACID):
原子性:事务是最小的执行单位,不允许分割。要不全部成功,要不全部回滚。
一致性:事务执行前后,数据保持一致。
隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰。也就是说多个事务并发执行时,一个事务的执行不影响其他事务的执行。
持久性:一个事务被提交后。他对数据的改变是持久的,即使数据发生故障也不应该对其有任何影响。
编程式事务管理
@TransactionTemplate或者@TransactionManger手动管理事务。应用很少
声明式事务管理
使用@Transactional
@Transactional(propagation=propagation.PROPAGATION_REQUIRED) public void aMethod { //do something B b = new B(); C c = new C(); b.bMethod(); c.cMethod(); }
PlatformTransactionManager: (平台)事务管理器,Spring 事务策略的核心。
TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
TransactionStatus: 事务运行状态。
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 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
@Transactional注解详细使用
作用范围:
方法:推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到public方法,否则不生效。
类:如果使用这个注解在类上,表明该注解对该类中所有的public方法都生效。
接口:不推荐
常用参数配置
@Transactional(propagation = Propagation.REQUIRED,timeout = 60000,isolation = Isolation.DEFAULT,readOnly = false,rollbackFor = Exception.class)
public String getInfo(){
return "wangyunzhao";
}
@Transactional 的使用注意事项总结
@Transactional 注解只有作用到 public 方法上事务才生效,不推荐在接口上使用;
避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效;
正确的设置 @Transactional 的 rollbackFor 和 propagation 属性,否则事务可能会回滚失败
Spring 事务中哪几种事务传播行为?
支持当前事务的情况:
- TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
- TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务的情况:
- TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
- TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。