Spring 事务管理原理探究
2、一个普通的JPA框架(此处是mybatis)的配置文件:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
.....
</bean>
这两个里面都配置了datasource,而且这个datasource的对象是在Spring的容器里面。一下提几个问题:

Spring 事务管理创造性的解决了很多以前要用重量级的应用服务器才能解决的事务问题,那么其实现原理一定很深奥吧?可是如果读者仔细研究了Spring事务管理的代码以后就会发现,事务管理其实也是如此简单的事情。这也印证了在本书开头的一句话“重剑无锋、大巧不工”,Spring并没有使用什么特殊的API,它运行的原理就是事务的原理。下面是DataSourceTransactionManager的启动事务用的代码(经简化):
protected void doBegin(Object transaction, TransactionDefinition definition)
{
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try
{
if (txObject.getConnectionHolder() == null)
{
Connection newCon = this.dataSource.getConnection();
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
if (con.getAutoCommit())
{
txObject.setMustRestoreAutoCommit(true);
con.setAutoCommit(false);
}
txObject.getConnectionHolder().setTransactionActive(true);
// Bind the session holder to the thread.
if (txObject.isNewConnectionHolder())
{
TransactionSynchronizationManager.bindResource(getDataSource(),txObject.getConnectionHolder());
}
}
catch (SQLException ex)
{
DataSourceUtils.releaseConnection(con, this.dataSource);
throw new CannotCreateTransactionException( "Could not open JDBC Connection for transaction", ex);
}
}
在调用一个需要事务的组件的时候,管理器首先判断当前调用(即当前线程)有没有一个事务,如果没有事务则启动一个事务,并把事务与当前线程绑定。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(); ……
}
从doBegin的代码中可以看到在启动事务的时候,如果Connection是的自动提交的(也就是getAutoCommit()方法返回true)则事务管理就会失效,所以首先要调用setAutoCommit(false)方法将其改为非自动提交的。setAutoCommit(false)这个动作在有的JDBC驱动中会非常耗时,所以最好在配置数据源的时候就将“autoCommit”属性配置为true。
Spring 事务管理原理探究的更多相关文章
- Spring事务管理机制的实现原理-动态代理
之前在做项目中遇到spring无法进行事务代理问题,最后发现是因为没有写接口,原因当时明白了,看到这篇文章写的清楚些,转过来 我们先来分析一下Spring事务管理机制的实现原理.由于Spring内置A ...
- Spring系列.事务管理原理简析
Spring的事务管理功能能让我们非常简单地进行事务管理.只需要进行简单的两步配置即可: step1:开启事务管理功能 @Configuration //@EnableTransactionManag ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- spring事务管理器设计思想(二)
上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...
- Spring事务管理--多个ORM框架在使用时的情况分析
公司的项目已经接近尾声了,总结一下项目中用到的技术,我发现项目中的有些东西还是挺模糊的,只是知道这么用就行了.并不清楚其中的原理.由于公司的项目比较老,是7年前的一个项目了,中间一直有人在维护,也是在 ...
- spring事务管理器设计思想(2)
spring事务管理器设计思想(二) 上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当 ...
- Spring事务管理——回滚(rollback-for)控制
探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...
- 阿里面试挂了,就因为面试官说我Spring 事务管理(器)不熟练?
前言 事务管理,一个被说烂的也被看烂的话题,还是八股文中的基础股之一.但除了八股文中需要熟读并背诵的那些个传播行为之外,背后的"为什么"和核心原理更为重要. 写这篇文章之前,我 ...
- Spring事务管理回滚问题
Spring事务管理不能回滚问题 在前段时间学习SpringMVC的练习中,碰到声明式事务管理时,事务不能回滚的情况,通过查看博客和资料,解决了问题. 原因 导致Spring事务管理不能回滚的原因有两 ...
随机推荐
- JsRender系列-11
<!DOCTYPE html> <html> <head> <script type="text/javascript" src=&quo ...
- 小米2000万买域名mi.com
来源:互联网的一些事 移动互联网之下,域名对于企业的吸引力将会越来越低,因为网站的入口多元化,不再仅凭域名.小米用超2000万人民币的代价购买mi.com域名,仅仅是为了所谓的国际化吗?小米此举, ...
- maven小试牛刀
Maven是一个采用纯Java编写的开源项目管理工具.Maven采用了一种被称之为project object model (POM)概念来管理项目,所有的项目配置信息都被定义在一个叫做POM.xml ...
- Eclipse常见设置及快捷键使用总结(更新中)
Eclipse中常见设置: 1.Eclipse在保存时设置自动去掉多余的import和格式化代码 路径: window --> preferences --> java --> Ed ...
- Python错误处理
中文注释出错,把UTF-8标明放在文件头就行了 # coding: utf-8
- C# 常用控件及单击事件
1.窗体 1.常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体. (2)WindowState属性: 用来获取或设置窗体的窗口状态. 取值有三种: No ...
- POJ 2449 A*+SPFA
A*算法求第k短路流程: 1)计算h[],即当前点到t的估计值 若为有向图,建立反向图求出h[].若为无向图,可直接求解h[].可通过SPFA求解. 2)A*搜索 每次找到新节点就直接加入队列,计算出 ...
- ASP.NET MVC 学习3、Controller左手从Model获取数据,右手传递到View页面
参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/accessing-your-models-dat ...
- 本来运行的好的Ajax.dll怎么突然不起作用了
客户中有个好多年前老项目用了Ajax.dll,前几天突然不起作用了. 问了下原因,系统从Windows Server2003 升级为 Windows Server 2008了,IIS也从6升级成7了. ...
- MasterPage的自身Bug还是?
如果不想每个页面都设置css样式,那就在MasterPage设置即可,但是有个问题就是路径并不能识别正确,所以必须让你的页面和MasterPage的页面在平级的位置. 例如MasterPage.mas ...