spring 事务原理
事务有原子性、一致性、隔离性、持久性的特点,在开发中我们将一组不可分割的操作放在事务中,要么一起成功,要么一起失败,例如最简单的转账,我们看一下spring是如何实现事务管理的。
spring事务的关键对象
spring的事务实现中有几个关键对象,我们先来认识一下:
PlatformTransactionManager
事务管理器接口只有三个方法:
getTransaction:获取当前激活的事务或者创建一个事务
commit:提交当前事务
rollback:回滚当前事务
PlatformTransactionManager有很多具体的实现:
DataSourceTransactionManager,使用JDBC与ibatis进行持久化
JtaTransactionManager:使用分布式事务
JpaTransactionManager:使用jpa
HibernateTransactionManager:使用hibernate
TransactionDefiition
TransactionDefiition是事务属性的定义,其中包含事务的隔离级别、事务传播类型、事务过期时间、事务是否可读等事务信息。
spring的隔离级别和数据库的是对应的,只是多了一个ISOLATION_DEFAULT
类型,表示使用mysql默认隔离级别。
spring的事务传播类型如下:
事务的具体实现
我们用一个简单的例子看一下spring的事务是如何实现的
新建一个账户表,包含几个基本字段,金额、姓名等
新建一个springboot工程,引入jdbc与mysql的依赖
新建一个service,在用一个controller调用此service的转账方法
为了探究spring是如何实现事务的,我们通过tcpdump抓mysql的包来看执行的语句
我们执行用户1给用户2转账5元,看到抓包结果为
可以看到,在第一个语句执行前设置为手动提交,在所有语句执行完后执行commit,最后再设置成自动提交。
如果中间执行失败呢,我们将 int i = 0 / 0;这行的注释打开,制造一个RuntimeException,看看执行结果
事务被执行回滚了。
分析事务代码
spring中可以用aop注入TransactionInterceptor,或者像前面的例子一样,在需要事务管理的方法上加上注解@Transactional,spring在此方法执行时会执行个方法的interceptor集合,事务的interceptor是org.springframework.transaction.interceptor.TransactionInterceptor
,它继承自TransactionAspectSupport,事务的具体实现在TransactionAspectSupport中。
TransactionInterceptor在执行时会调用方法invoke
在invokeWithinTransaction中会调用createTransactionIfNecessary方法
tm.getTransaction(txAttr);这里会使用具体持久化方式对应的那个TransactionManager,楼主使用的Jdbc,实现是DataSourceTransactionManager,getTransaction方法调用的是父类中的方法
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
startTransaction会调用DataSourceTransactionManager的doBegin方法设置当前连接为手动提交事务
再看回org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction方法,这里显示了aop如何处理事务
再看一下completeTransactionAfterThrowing方法,如果是需要回滚的异常则执行回滚,否则执行提交
总结
spring中的事务实现从原理上说比较简单,通过aop在方法执行前后增加数据库事务的操作。
1、在方法开始时判断是否开启新事务,需要开启事务则设置事务手动提交 set autocommit=0;
2、在方法执行完成后手动提交事务 commit;
3、在方法抛出指定异常后调用rollback回滚事务
spring事务管理有很多细节的处理,如传播方式的实现,感兴趣的同学自己去看看源码喽~
版权声明: 本文为 InfoQ 作者【年轮】的原创文章。
原文链接:【http://xie.infoq.cn/article/52f38883e28821c9cf0a608ea】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论