spring 事物处理
作者:binspring里面,事物分2种,编程式事物、声明式事物
编程式事物:使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate
声明式事物:是建立在AOP之上的,配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式)
我们着重介绍声明式事物,我们可以使用@Transactional注解标注方法(非静态)和类来开启事物,
spring事物的实现原理,在注解方法执行前关闭自动提交,con.setAutoCommit(false),在注解方法执行完后进行commit
我们来看注解:
public @interface Transactional { //通过bean name指定事物管理器 String transactionManager() default ""; //传播行为,主要有REQUIRED、REQUIRE_NEW、NESTED等 Propagation propagation() default Propagation.REQUIRED; //隔离级别,读未提交、读已提交、可重复读、串行,可以参考mysql事物隔离级别,一样的 Isolation isolation() default Isolation.DEFAULT; //超时时间 int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; //是否只读事物 boolean readOnly() default false; //指定在出现什么异常时回滚 Class<? extends Throwable>[] rollbackFor() default {}; //指定出现什么异常名称时回滚 String[] rollbackForClassName() default {}; //指定出现什么异常时不回滚,默认时所有异常都回滚 Class<? extends Throwable>[] noRollbackFor() default {}; //指定出现什么异常名称时不回滚,默认时所有异常都回滚 String[] noRollbackForClassName() default {}; }
主要介绍事物都传播级别:
REQUIRED :如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起,具体实现方式就是:
将当前事物的配置信息放到threadLocal的变量中,然后开启一个新的事物,等新的事物执行完成后,在从Threadlocal中恢复
SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
NEVER:以非事务方式运行,如果当前存在事务,则抛出异常
MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于REQUIRED
同线程开启多个事物时,db的connection是通过当前线程都TreadLoacl管理的,通过DataSource(key)->Connection(value)键值对形式保存的.