`
tianshibaijia
  • 浏览: 1128834 次
文章分类
社区版块
存档分类
最新评论

Spring @Transactional 如何开启事务

 
阅读更多

Spring @Transactional 如何开启事务

java.lang.Object

org.springframework.transaction.support.TransactionSynchronizationManager


public abstract class TransactionSynchronizationManager

extends Object

Central helper that manages resourcesand transaction synchronizations per thread.

为每个线程管理资源和事务的中心helper


hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext时,

@Transactional,Spring的事务管理器HibernateTransactionManager.doBegin()方法开启的Session和事务 就是绑定到TransactionSynchronizationManager的上下文中的..


SpringSessionContext.currentSesssion()方法就是在TransactionSynchronizationManager的上下文中查找的..


上文回顾:

现在对于hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext时的getCurrentSession()就很清楚了:

1:@Transactional声明的方法执行时,Spring的TransactionManager会自动Open Sesion,自动开启事务,并且将此Sesion绑定到SpringSessionContext(实际上是TransactionSynchronizationManager的ThreadLocal的Map)中..

2:SessionFactory.getCurrentSession()方法执行时,调用SpringSessionContext.currentSession()从TransactionSynchronizationManager的上下文中查找 当前的Session

3:找到后返回当前的Session,找不到,则返回HibernateException("NoSessionfound for current thread")

上述第一点是未验证的,现在我们来分析一下源代码:






先进入到JdkDynamicAopProxyimplements.invoke()方法

然后到ReflectiveMethodInvocation. proceed(),这里调用TransactionInterceptor.invoke(this)方法:

典型的拦截器模式:

1:按需开启事务

2:递归执行下一个拦截器 或 执行代理目标方法

3:提交事务



进入createTransactionIfNecessary(tm,txAttr, joinpointIdentification), 其中的tm.getTransaction(txAttr); //这一句应该是取得事务的,跟进去

……………………………………….

AbstractPlatformTransactionManager.getTransaction()方法:

如果当前有事务,取出并根据事务传播行为的配置去处理,如果当前没有事务,调用doBegin开启一个新事务





HibernateTransactionManager.doGetTransaction()方法:

尝试获取当前已绑定到TransactionSynchronizationManager的上下文的事务,主要为事务传播行为而设




HibernateTransactionManager.doBegin()方法:

开启一个新的事务,并放进TransactionSynchronizationManager的上下文中,绑定到当前线程)







Spring @Transactional 如何开启事务 总结:


@Transactional声明的方法执行时会调用AbstractPlatformTransactionManager.getTransaction()取得当前事务


getTransaction()的执行流程如下:

1:尝试获取当前已绑定到TransactionSynchronizationManager的上下文的事务

(调用HibernateTransactionManager.doGetTransaction()方法)


2:如果取得已存在的事务,则根据事务传播属性的设置来处理

(调用AbstractPlatformTransactionManager.handleExistingTransaction()方法)


3:如果没有事务,则打开新的Session,开启新的事务,并将该Session和事务绑定到TransactionSynchronizationManager的上下文中

(调用HibernateTransactionManager.doBegin()方法)



-------------------------------------------------

核心还是理解TransactionSynchronizationManager,要懂得Spring的TransactionManager开启事务后是以键值对<SessionFactory,SessionHolder>形式 存放到TransactionSynchronizationManager的ThreadLocal的Map的上下文中(以ThreadLocal的方法与当前线程绑定).


























  


  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics