`

【转载】TransactionSynchronizationManager理解

 
阅读更多
发现
 protected void setUp() throws Exception
    {
      super.setUp();
      context = new FileSystemXmlApplicationContext(springConfigFile);
     if (bHoldSession)
    {
  sessionFactory = (SessionFactory) context.getBean("sessionFactory");
  Session session = SessionFactoryUtils.getSession(sessionFactory, true);
  TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
    }
 }
对 TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));的理解如下:
在调用一个需要事务的组件的时候,管理器首先判断当前调用(即当前线程)有没有一个事务,如果没有事务则启动一个事务,并把事务与当前线程绑定。Spring使用TransactionSynchronizationManager的bindResource方法将当前线程与一个事务绑定,采用的方式就是ThreadLocal,这可以从TransactionSynchronizationManager类的代码看出。
public abstract class TransactionSynchronizationManager
{
 ……
 private static final ThreadLocal currentTransactionName = new ThreadLocal();
 private static final ThreadLocal currentTransactionReadOnly = new ThreadLocal();
 private static final ThreadLocal actualTransactionActive = new ThreadLocal(); ……
}
再看看方法SessionHolder的理解

先看一段代码:
    Connection conn = Conn.getConnection();
    conn.setAutoCommit(false);
    ……..
    ……...
    conn.rollback();
    conn.commit();

    数据库的事务是针对 Connection 的。

    接着再看一段代码:( spring 中事务的一段学习代码,这段代码是把 spring 和 hibernate 结合在一起的,增加了理解上的难度,因为我的出发点一开始不要 hibernate ,就光用 jdbc 来进行数据库事务,但是没有其他好的代码,就这样吧)

    public Long addLineItem(Long orderId, LineItem lineItem){

       log("OrderListDAOHibernate.addLineItem : Start...");

       OrderList orderList = (OrderList) getHibernateTemplate().load(OrderList.class, orderId);

       lineItem.setOrderList(orderList);

       getHibernateTemplate().saveOrUpdate(lineItem);

       getHibernateTemplate().saveOrUpdate(orderList);

       log("OrderListDAOHibernate.addLineItem : Ending...");

       return lineItem.getId();

    }

    在这个代码的配置文件中,把 addLineItem 做为一个切入点,进行事务,也就是说,在 addLineItem 的外面,再包上一层事务的外壳。

    但是这个时候,问题出来了,事务是针对 Connection 的,而上面的两个连续的 HibernateTemplate 执行的 saveOrUpdate 中的 Connection 必须是一致才能用事务, spring 怎么做到这一点的呢?(这个问题也就是在找 spring 的事务例子前,我想的 spring 中用 jdbc 来进行事务,怎么样让 Connection 保持一致呢?但是没有 jdbc 的例子,只有整合 hibernate 或者 ibatis 的例子,但是,我想,原理是一样的吧。)

    解决问题的思路: HibernateTemplate 中的 Connection 必定一致。那么就从 HibernateTemplate 入手。

    看 spring 的源代码,既然是 Hibernate ,那么,就没有 Connection 给你看,只有 Session ,由 Session 来管理 Connection ,那么用事务来控制的话,这个 Session 必定在所有该事务中是一致的。于是在 HibernateTemplate 中找到:
protected Session getSession() {

       if (isAlwaysUseNewSession()) {

return SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor());

       }

       else if (!isAllowCreate()) {

return SessionFactoryUtils.getSession(getSessionFactory(), false);

       }

       else {

return SessionFactoryUtils.getSession(

                  getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator());

       }

    }

 

看来在 SessionFactoryUtils 里面,接着在 SessionFactoryUtils.getSession 中找:

这个方法太长了,太复杂了,从简,发现了非常关键的一点:

SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

假如 sessionHolder 不等于空,说明,在事务中有这样一个还没有 commit 的 session ,那么就返回这个 session ,假如等于空,新建一个 session ,并且在事务里加入这个 session 。这段代码的意思大概是这样,太繁杂了,只能猜,也肯定是如此。

 

再看 getHibernateTemplate() 方法来自继承 HibernateDaoSupport ,看了电子书《 spring-reference 》的第九章“ Dao 支持”, Dao 的支持类可以有好多,如: JdbcDaoSupport , HibernateDaoSupport , JdoDaoSupport 等等。

 

既然前面一开始就是从 jdbc 的 spring 事务控制引起的,那么看到了同样的 HibernateDaoSupport---JdbcDaoSupport ,那么 JdbcDaoSupport 也应该有 getJdbcTemplate() 这个方法,并且返回 JdbcTemplate 这个类。
果然如此。
于是剖析 JdbcTemplate 是不是和 HibernateTemplate 一样。果然一样。
注意到:

Connection con = DataSourceUtils.getConnection(getDataSource());

Connection 是从 DataSourceUtils.getConnection() 来的,继续跟踪 DataSourceUtils.getConnection() 。

找到:

ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);  

和 Hibernate 中的一模一样,因为没有了 session 的封装,条理在 jdbc 中更加清晰了。

 

 

 

 

 


分享到:
评论

相关推荐

    edb:春天的 jfinal

    DataSource 数据源对象和 jfinal 的配置类 com.jfinal.plugin.activerecord.Config和 spring事务相关的 DataSourceUtils.getConnection、ConnectionHolder、TransactionSynchronizationManager.getResource 类和方法...

    Spring高级之注解驱动开发视频教程

    视频详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 1、课程简介 Spring框架是一系列应用框架的核心,也可以说是整合其他应用框架的基座。...n 源码分析-TransactionSynchronizationManager

    SPRING API 2.0.CHM

    All Classes AbstractAdvisorAutoProxyCreator AbstractApplicationContext AbstractApplicationEventMulticaster AbstractAspectJAdvice AbstractAspectJAdvisorFactory AbstractAspectJAdvisorFactory....

    node-v4.8.6-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基础运维技能(下)md格式笔记

    基础运维技能(下)md格式笔记

    node-v8.1.2-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    黑马程序员 C语言学习笔记

    持续更新

    PCL-1.14.1-AllInOne-msvc2022-win64+pdb-msvc2022-win64

    PCL-1.14.1-AllInOne-msvc2022-win64+pdb-msvc2022-win64

    DSmall商城系统源代码

    PC商城系统源码

    Defender Control v2.1(win11 禁用defender服务工具).zip

    Defender Control v2.1(win11 禁用defender服务工具).zip

    node-v8.8.0-linux-armv6l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v8.9.0-linux-ppc64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v4.7.2-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2024年中国超声非侵入式腐蚀检测传感器行业研究报告.docx

    2024年中国超声非侵入式腐蚀检测传感器行业研究报告

    基于知识图谱的问答系统,结合MetaQA知识图谱,用于解决电影领域的问答问题

    【作品名称】:基于知识图谱的问答系统,结合MetaQA知识图谱,用于解决电影领域的问答问题 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 ## 项目目录结构: 1、train_KGE目录下为训练知识图谱嵌入模型的相关代码,包含以下知识图谱嵌入方法: - RotatE - TransE - DistMult - ComplEx 2、KGQA_system目录下包含了问答系统的实现代码,包含以下几个模块: - 知识图谱嵌入模块 - 问题嵌入模块 - 关系预测模块 - 答案生成模块

    node-v8.8.0-linux-ppc64le.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    ISO 3452-3-2013 无损检测渗透检测第3部分:参考试块.pdf

    ISO 3452-3-2013 无损检测渗透检测第3部分:参考试块.pdf

    node-v8.1.1-linux-armv6l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    用于目标检测的遥感图像数据集

    目标检测遥感数据集。包括训练集、验证集和测试集共1400张遥感图像及相应标注。已处理为适用yolov5的格式。

Global site tag (gtag.js) - Google Analytics