直接使用springboot操作下编程式事物的管理使用,主要是springboot很多配置和中间实现都省略了,一键注入就可以。
一、transactionTemplate方式
@Componentpublic class ProgramTransaction {Logger logger = LoggerFactory.getLogger(ProgramTransaction.class);@AutowiredTransactionTemplate transactionTemplate;@AutowiredUserDao userDao;public void TransactionTemplate(){//开启事务保存数据boolean result = transactionTemplate.execute(new TransactionCallback<Boolean>() {@Overridepublic Boolean doInTransaction(TransactionStatus status) {try {programInsert1();} catch (Exception e) {//TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 手动开启事务回滚status.setRollbackOnly();logger.error(e.getMessage(), e);return false;}return true;}});}// 使用方式1 直接public void programInsert1(){User user = new User();user.setName("programInsert1");user.setAge(34);user.setCountry("zouhui222");userDao.insert(user);}}
这种方式直接就可以注入
@AutowiredTransactionTemplate transactionTemplate;
是因为springboot在启动时候,自动会去实例化具有@configration注解的类,于是乎根据@Bean注解实例对应的对象放到spring容器中,这里面主要是因为有个@ConditionOnMissingBean注解会去容器中寻找是否有过实例化TransactionTemplate,如果没有,就直接实例化一个放到容器中,所以开始的时候注入这个没有问题。(这个依赖springboot启动时候注入的对象,在编译时期是不知道,也就是说在idea编辑器中不会提示它的实例化在哪里实现的,只有启动之后才会去绑定,图中跳转实例标识)
@ConditionalOnMissingBean


这个注入原理,后面有时间可以继续研究下,sprigboot自动化的东西,就是方便。
tranactionTemplate通过调用execute方法匿名内部类,将需要事物的操作放在doInTransaction方法里面,通过手动捕获异常手动回滚。上图中,其实也可以看到这个transactionTemplate底层还是嵌套包裹了PlatformTransactionManager这个管理器的。当有事物的操作不放进try-catch里面时候,虽然程序遇到异常退出,但是事物也没有提交成功,自动回滚了。



这样子虽然事物回滚了,但是对于程序来说不友好,所以还是建议自己的事物放进try-catch 里面,手动自己回滚,也更方便。
二、transactionManager方式进行
public void programInsert1(){User user = new User();user.setName("programInsert2");user.setAge(34);user.setCountry("zouhui222");userDao.insert(user);int a = 10 0;}@AutowiredPlatformTransactionManager transactionManager;@AutowiredTransactionDefinition transactionDefinition;public void transactionManager(){System.out.println("default isolation="+transactionDefinition.getIsolationLevel());System.out.println("default propagation="+transactionDefinition.getPropagationBehavior());TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);System.out.println("rollbackonly="+transaction.isRollbackOnly());System.out.println("iscompleted="+transaction.isCompleted());try {programInsert1();transactionManager.commit(transaction);} catch (Exception e) {System.out.println("出现异常了 异常信息是:"+e.getMessage());System.out.println("iscompleted2="+transaction.isCompleted());transactionManager.rollback(transaction);}}
手动提交事物手动自己捕获异常进行回滚,这个就是事物管理器了,也是上面一个方法的底层的调用。在springboot很多东西都有自定义的,默认的,比如TransactionDefinition PlatformTransactionManager都是springboot启动时候初始化出来的。可以看出来,这样子的默认的隔离级别是-1相当于走数据库自己的默认隔离级别了,mysql的inndb引擎就是读已提交级别了。传播属性是0,这个就是默认的required。
spring的7中传播属性的枚举值类如下:

对于编程式事物的事物传播性:
@AutowiredPlatformTransactionManager transactionManager;@AutowiredTransactionDefinition transactionDefinition;public void transactionManager(){System.out.println("default isolation="+transactionDefinition.getIsolationLevel());System.out.println("default propagation="+transactionDefinition.getPropagationBehavior());TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);System.out.println("rollbackonly="+transaction.isRollbackOnly());System.out.println("iscompleted="+transaction.isCompleted());try {transactionManager2();programInsert1();transactionManager.commit(transaction);} catch (Exception e) {System.out.println("出现异常了 异常信息是:"+e.getMessage());System.out.println("iscompleted2="+transaction.isCompleted());transactionManager.rollback(transaction);}}public void transactionManager2(){// 定义事务属性DefaultTransactionDefinition td = new DefaultTransactionDefinition();td.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);System.out.println("default isolation="+td.getIsolationLevel());System.out.println("default propagation="+td.getPropagationBehavior());TransactionStatus transaction = transactionManager.getTransaction(td);System.out.println("rollbackonly="+transaction.isRollbackOnly());System.out.println("iscompleted="+transaction.isCompleted());try {programInsert2();transactionManager.commit(transaction);} catch (Exception e) {System.out.println("出现异常了 异常信息是:"+e.getMessage());System.out.println("iscompleted2="+transaction.isCompleted());transactionManager.rollback(transaction);}}public void programInsert2(){User user = new User();user.setName("programInsert22");user.setAge(34);user.setCountry("zouhui222");userDao.insert(user);}
transactionManager2定义了自己的事物属性:隔离级别、传播性是new_supports新开一个事物。transactionManager方法调用transactionManager2方法时候,两者的事物是相互独立不影响的,内部transactionManager2是正常提交,外层事物回滚。 通过该编程式事物可以发现,具有注解声明式的优点就是,可以自己类中使用事物传播属性,无需跨类或者自己注入自己代理的麻烦。
三、事物底层源码解析初探
首先从获取事物状态类这个开始:org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
TransactionStatus transaction = transactionManager.getTransaction(td);

protected Object doGetTransaction() {//获取数据源事物对象 是数据源事物管理的一个静态内部类实例对象 继承了JdbcTransactionObjectSupportDataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject();txObject.setSavepointAllowed(this.isNestedTransactionAllowed());ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.obtainDataSource());txObject.setConnectionHolder(conHolder, false);return txObject;}
然后就进行事物的一些初始化动作,比如初始化默认事物状态类、获取连接池中、准备同步操作等
//此处 针对嵌套事物时候的事物管理器中资源的挂起或者暂停 没有嵌套时候// 相首次事物管理器的初始化 没有这个对象 所以传nullAbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources = this.suspend((Object)null);if (debugEnabled) {this.logger.debug("Creating new transaction with name [" + ((TransactionDefinition)definition).getName() + "]: " + definition);}try {// 是否是新同步状态boolean newSynchronization = this.getTransactionSynchronization() != 2;// 初始化默认的事物状态 根据自己自定义的事物属性或者默认自定义属性DefaultTransactionStatus status = this.newTransactionStatus((TransactionDefinition)definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);//初始化连接 设置隔离级别 设置自动提交为手动提交 设置事物连接状态truethis.doBegin(transaction, (TransactionDefinition)definition);//同步状态准备 做些全局属性的设置 当前事物隔离级别 、事物只读、事物是否启动等// 主要是这个抽象类org.springframework.transaction.support.TransactionSynchronizationManagerthis.prepareSynchronization(status, (TransactionDefinition)definition);return status;} catch (Error | RuntimeException var7) {this.resume((Object)null, suspendedResources);throw var7;}

至此事物的一些初始化、准备工作搞定
然后操作事物,进行事物的提交:
提交事物主要走着个方法org.springframework.transaction.support.
AbstractPlatformTransactionManager#processCommit

最后提交事物给数据库:
org.springframework.jdbc.datasource.DataSourceTransactionManage#doCommit;DataSourceTransactionManage 继承的是
AbstractPlatformTransactionManager
备注:源码初探,对于内部的一些定义还是不够了解深入,这次只是初识事物大致流程:连接池获取连接(也就是连接会话)-》设置隔离级别-》设置管理器全局属性-》提交事物(或者回滚事物)-》清空管理器当前连接的全局属性。







