继续学习TransactionManager。上一篇分析了一小部分PlantformTransactionManager的getTransaction方法……这部分内容确实很丰富,但是Spring的事务管理大部分是在TransactionManager中实现的。分析完事务管理器的功能,基本就算掌握了Spring的事务管理。今天应该从startTransaction说起,它定义在AbstractPlantFormTransactionManager中。startTransaction前面说过,startTransaction是事务真正开始的地方。首先,创建一个DefaultTransactionStatus,因为我们知道交易状态对象最终会在交易开启时返回。调用doBegin开始事务。然后调用prepareSynchronization方法清理善后工作。我们在上一篇文章中已经看到了这种方法。将当前事务的字段数据绑定到当前线程并保存。privateTransactionStatusstartTransaction(TransactionDefinitiondefinition,Objecttransaction,booleandebugEnabled,@NullableSuspendedResourcesHoldersuspendedResources){booleannewSynchronization=(getTransactionSynchronization()!=SYNCHRONIZATION_NEVER);DefaultTransactionStatusstatus=newTransactionStatus(definition,transaction,true,newSynchronization,debugEnabled,suspendedResources);doBegin(交易,定义);准备同步(状态,定义);返回状态;}继续跟踪doBegin方法。doBegindoBegin方法跳转到DataSourceTransactionManager去实现,因为我们说过当我们真正需要和数据库打交道的时候,我们会跳转到事务管理的登陆实现类。首先获取DataSource(其实就是事务对象),然后定义我们非常熟悉的数据库连接Connection。看到这个Connection,你会不会有点惊讶?因为我们一步步接触到了Spring事务管理的底层实现。protectedvoiddoBegin(Objecttransaction,TransactionDefinitiondefinition){DataSourceTransactionObjecttxObject=(DataSourceTransactionObject)交易;连接con=null;之后判断当前事务对象是否已经有ConnectionHolder,如果没有,就创建一个ConnectionHolder对象,让它持有新创建的数据库连接。try{if(!txObject.hasConnectionHolder()||txObject.getConnectionHolder().isSynchronizedWithTransaction()){连接newCon=obtainDataSource().getConnection();if(logger.isDebugEnabled()){logger.debug("AcquiredConnection["+newCon+"]forJDBCtransaction");}txObject.setConnectionHolder(newConnectionHolder(newCon),true);然后,从ConnectinHolder重新获取连接:txObject.getConnectionHolder().setSynchronizedWithTransaction(true);con=txObject.getConnectionHolder().getConnection();然后是你非常熟悉的最激动人心的:if(con.getAutoCommit()){txObject.setMustRestoreAutoCommit(true);if(logger.isDebugEnabled()){logger.debug("将JDBC连接["+con+"]切换为手动提交");}con.setAutoCommit(错误的);}设置数据库连接的autoCommit为false,即开启事务后,设置事务为active状态,并根据事务定义设置超时等操作:prepareTransactionalConnection(con,definition);txObject.getConnectionHolder().setTransactionActive(true);inttimeout=determineTimeout(定义);如果(超时!=TransactionDefinition.TIMEOUT_DEFAULT){txObject.getConnectionHolder()。setTimeoutInSeconds(超时);}最后一步://将连接持有者绑定到线程。如果(txObject.isNewConnectionHolder()){TransactionSynchronizationManager.bindResource(obtainDataSource(),txObject.getConnectionHolder());}是将ConnectionHolder绑定到当前线程。如果你没有忘记,TransactionSynchronizationManager是用来判断当前是否有打开的事务。当然,开启的交易本来就是他持有的,当然要由他来判断了。至此,数据库事务就完美开启了。同时,在Spring事务管理器当前事务已经开启的情况下,getTransaction代码的逻辑分析我还没有分析完。下一篇Spring事务框架之事务管理器(三)上一篇Spring事务框架之事务管理器(一)
