事务支持分析

java事务实现世界可分为两种
一种是jdbc事务,也叫本地事务,令外一种是JTA事务,也叫全局事务。简要介绍下JTA API
javax.transaction.Status JTA事务状态,使用方式 常被作为判断条件做处理
javax.transaction.Synchronization 定义了事务完成前后改做的事,使用方式一般是先注册,在适当的时机调javax.transaction.Transaction 定义了操作全:事务提交,回滚,绑定或解绑资源事务与资源,获取状态,设置回滚,同步
javax.transaction.TransactionManager定义了事务的所有动作,一般由应用服务器采用jts实现
javax.transaction.TransactionSynchronizationRegistry定义了同步,但是同步的调用时机更接近2阶段提交,也就是说beforeComplete晚于Transaction注册的beforeComplete执行,afterComplete早于Transction的afterComplete执行
javax.transaction.UserTransaction提供给应用客户端化分事务边界的方法
javax.transaction.xa.XAResource定义了资源管理器与事务管理器的通信
javax.transaction.xa.Xid定义了资源事务关联的唯一标识,就好比树的枝干,每个资源管理器做的事就对应一条枝干的标识,而所有的枝干都长在一个树上象征着在每个资源管理器上做的事就对应着整颗树。Xid中包括全局事务格式,标识,分支标识。
为了更好的理解JTA实现,可参看更好的理解JTA。
org.hibernate.Transaction统一了各种事务的具体实现
JDBCTransaction
JTATransaction
CMTTransaction(事务托管给应用服务器完成)
三者都认为一个session只能允许同一时刻只能由一个未提交事务,实现中大量代码主要体现在事务提交前前后后的同步问题,我们将同步分为本地同步和JTA同步,之所以分开讨论,是因为这两种同步不能同时存在以上三种之一实现中。
如果条件flushBeforeCompletionEnabled||autoCloseSessionEnabled||connectionReleaseMode ==ConnectionReleaseMode.AFTER_TRANSACTION,即事务完成之前是否flush session,事务完成之后事务自动关闭 session,连接释放是否在提交事务之后 不为真,那么认为本地同步;
如果为真,则进行如下判断
如果采用的实现类是JBCTransaction或者TransactionManager没找到或者事务已经完成(提交或回滚,未激活等)或事务被标识为回滚,则为本地同步
否则,为JTA同步。
JDBCTransaction中
如果为本地同步并且flushmode !=Flushmode.Never则刷新session
如果为本地同步,则执行org.hibernate.jdbc.JDBCContext中的beforeTransactionCompletion和afterTransactionCompletion,同时执行synchronizations集合中的各个同步类(都是javax.transaction.Synchronization实现)
JTATransaction中
如果不是JTA同步,则认为是本地同步
如果是JTA同步,则同步方法的执行又JTA实现自动完成,hibernate不干预
如果是本地同步或!flushBeforeCompletionEnabled并且flushModel!=flushModel.Never,则刷新session
如果是本地同步并且JTA事务是通过Transaction begin启动,则执行beforeTransactionCompletion
如果JTA不是通过Transaction begin启动,则Transaction commit并不会真正触发提交
如果是本地同步,则执行afterTransactionCompletion
CMTTransaction中
如果不是JTA同步,Transaction begin抛出异常
如果是JTA同步并且!flushBeforeCompletionEnabled并且flushModel!=flushModel.Never,则刷新缓存
三种实现的总结:
JDBCTransaction只会执行本地同步
它通过java.sql.Connection实现,并会执行JdbcContext.beforeTransactionCompletion和afterTransactionCompletion
JTATransaction既可以进行JTA同步,也可进行本地同步;
它通过userTransaction实现,
但在调用Transaction begin方法之前,事务允许通过userTransaction.begin开始,如果不是调用Transaction begin开启事务的,那自然就不会调用JdbcContext.beforeTransactionCompletion。如果是本地同步的话,还可以调用jdbcContext.afterTransactionCompletion
CMTTransaction不会进行实质性的事务开始,提交,回滚,超时,只设置回滚标志,当调用Transaction begin方法时会调用registerSynchronizationIfPossible而此时会在事务管理器上注册同步org.hibernate.transaction.CacheSynchronization,间接调用调用JdbcContext.beforeTransactionCompletion和afterTransactionCompletion,
三种事务的创建由对应的JDBCTransactionFactory,JTATransactionFactroy,CMTTransactionFactory完成
这三者区别在
connectionReleaseMode
JTATransactionFactroy和CMTTransactionFactory连接释放模式执行每条语句后释放连接,JDBCTransactionFactory事务提交后释放,因此jta事务连接的重用高
TransactionManager
JDBCTransactionFactory和JTATransactionFactroy不需要TransactionManager,CMTTransactionFactory必须
isTransactionInProgress
JDBCTransactionFactory确定执行JDBCTransaction begin方法,但没提交或回滚过视为正在进行
JTATransactionFactroy
通过缓存的JTATransaction.getUserTransaction状态确定
如果找不到,通过transactionManager状态确定
如果找不到,通过JNDI查找userTransaction状态确定
CMTTransactionFactory
通过transactionManager.getTransaction状态确定
factory通过org.hibernate.transaction.TransactionFactoryFactory.buildTransactionFactory确定,简单表述下
通过hibernate.transaction.factory_class确定,如果为空,返回JDBCTransactionFactory
否则实例化hibernate.transaction.factory_class指定类,并调用configure方法

事务管理器transactionManager
TransactionManagerLookupFactory.getTransactionManagerLookup根据hibernate.transaction.manager_lookup_class确定TransactionMangerLookup,简要介绍TransactionMangerLookup
public TransactionManager getTransactionManager(Properties props) throws HibernateException//获取JTA 事务管理器
public String getUserTransactionName();//获取JTA UserTransaction的JNDI名称
TransactionManager实现方式可分为通过JNDI查找实例和通过实例化方式;
如WeblogicTransactionManagerLookup会在JNDI上下文中查找名称为javax.transaction.TransactionManager的事务管理器
而WebSphereTransactionManagerLookup根据webSphere服务器版本加载对应的class,查找顺序为
5.1 ->com.ibm.ws.Transaction.TransactionManagerFactory
5.0->com.ibm.ejs.jts.jta.TransactionManagerFactory
4.0->com.ibm.ejs.jts.jta.JTSXA
这些类都实现了getTransactionManager静态方法,通过java反射机制获取事务管理器
JOnASTransactionManagerLookup加载org.objectweb.jonas_tm.Current,再通过反射机制调用getTransactionManager静态方法
JOTMTransactionManagerLookup加载org.objectweb.jotm.Current
当然还提供了LocalTransactionManagerLookup,查找spring管理的JTA TransactionManager实现(通过注入LocalSessionFactoryBean的transactionManager属性。

你可能感兴趣的:(事务支持分析)