聊聊Spring事务管理

事务是一组操作的原子执行,其中任何一笔操作失败将导致全部操作撤销。

什么是事务?

如上所言,事务遵循ACID原则,A是原子性(atomicity);B是一致性(consistency),事务执行前后涉及到的相关数据保持一致;C是隔离性(isolation),事务正确提交之前结果不应被其他事务所见;D是持久性(durability),执行结果得到持久保存。这对于金融系统和交易类业务处理系统至关重要。

面向单一事务资源(数据库或应用服务)的称之为本地事务,java可通过JDBC的Connection实现;面向多个事务资源的分布式同步管理的称之为全局事务,java可通过JTA按照XA的二阶段提交方式实现。

Spring事务管理方式

Spring事务管理框架对JDBC、JTA事务处理进行了更高一层抽象,向开发人员提供了统一的开发接口,面对本地事务和全局事务使用一种编程模型,从而大大降低了开发的复杂度。

在开发中使用spring进行事务管理,需要首先在配置文件中进行transactionManager的配置,然后通过编程方式或者声明方式调用事务处理。

1、配置transactionManager

本地事务

基于JDBC事务管理器配置示例如下:

dataSource属性指定需要事务管理的javax.sql.DataSource对象。

全局事务

大部分应用服务器容器提供JTA支持,配置好JNDI数据源和JtaTransactionManager即可。

"dataSource"表示从JNDI中获取数据源,"transactionManager"是JTA事务管理器,其中属性transactionManagerName是其JNDI命名。

Spring还提供了对特定应用服务器事务管理器集成的支持,如:WebLogicJtaTransactionManager、WebSphereUowTransactionManager、OC4JJtaTransactionManager。

Tomcat容器本身不支持JTA,但可以借助于第三方JTA管理器实现,如JOTM(Java Open Transaction Manager )或AtomikosTransactionsEssentials。

2、编程式

应用需要调用Spring提供的PlatformTransactionManager、TransactionDefinition 和 TransactionStatus 三个核心接口。下面以银行账户之间转账例子说明。

此外,Spring还提供了更为简化的TransactionTemplate开发接口。

3、声明式

声明式通过配置或注解方式将事务管理与业务逻辑代码独立,开发人员只需在配置文件中做相应的事务规则声明或注解,便可以将事务规则通过AOP横切应用到业务逻辑中。支持TransactionInterceptor、TransactionProxyFactoryBean多种配置方式,Spring 2.x 引入了  命名空间和基于 Annotation 的方式,使得事务规则的声明配置更为简单方便。

基于  命名空间的声明式事务管理

基于 @Transactional 的声明式事务管理

通过在业务处理接口、接口方法、类以及类方法上添加@Transactional注解便可实现事务配置。

在配置文件中仅仅需要开启注解开关

这两种方式各有优点:基于  的方式,可通过切点表达式批量匹配多个方法;基于@Transactional 注解方式更为简单明了。

Spring事务管理原理

Spring事务管理框架包括三层:接口层、实现层和适配层。

接口层面向应用和拦截类提供简单统一的访问接口;实现层实现了Spring事务管理框架的主要逻辑,并定义了子类的抽象方法;适配层通过实现框架类将各种持久层的访问类库统一集成到Spring的事务管理框架之中。

1、接口层

Spring事务管理框架通过PlatformTransactionManager、TransactionDefinition、TransactionStatus接口向上层应用提供事务处理控制方法(getTransaction、commit、rollback),其中TransactionDefination接口定义事务各种属性;TransactionStatus保存事务执行状态;PlatformTransactionManager是向上层应用提供事务处理方法的接口。详见图1,这些接口在spring-tx包中定义。

图1:Spring事务处理框架接口类


TransacctionDefinition对事务的各种传播行为和隔离级别进行了定义。



2、实现层

Spring事务管理框架按照"1)接口层"的定义在org.springframework.transaction.support包中提供了实现类,主要包括:AbstractPlatformTransactionManager、DefaultTransactionDefinition、DefaultTransactionStatus、SuspendedResourceHolder、TransactionSynchronizationManager等。AbstractPlatformTransactionManager、DefaultTransactionDefinition、DefaultTransactionStatus分别继承实现了PlatformTransactionManager、TransactionDefinition、TransactionStatus接口。


图2:spring事务处理框架实现类

如图2中所示,AbstractPlatformTransactionManager实现了多事务处理的主要逻辑,其中私有方法suspend(Object transaction)和resume(Object transaction,SuspendedResourcesHolder resourcesHolder)实现了对嵌套事务的外部事务进行调度管理,suspend方法在getTransaction调用中被触发,resume方法在commit和rollback调用中被触发。

AbstractPlatformTransactionManager类中定义的一系列doXXX方法(如: doGetTransaction等)是对底层不同事务处理具体实现方法的封装,具体实现类需要实现这些方法(如:DataSourceTransactionManager)。这些方法中定义的Object transaction和Object suspendedResources两个参数是关键数据,transaction相当于实现层内部定义使用的transactionStatus类,suspendedResources是实现层定义的相关资源类,它们都是Object类型,AbstractPlatformTransactionManager只对它们的值进行保存和传递,DefaultTransactionStatus中定义的两个属性对之对应。

SuspendedResourceHolder类是对嵌套事务的当前外部事务的资源暂存,对应保存在当前DefaultTransactionStatus中的suspendedResources属性。

图3: 事务处理同步管理类


图3中,TransactionSynchronizationManager是当前事务处理的上下文数据管理类,resources是当前事务所使用到的资源,如:DataSourceTransactionManager用于保存对应数据源的ConnectionHolder; synchronizations管理事务处理过程中各阶段各种资源所需要做的同步处理操作,如:ConnectionSynchronization事务执行过程中对链接的绑定与解绑,SpringLobCreatorSynchronization在事务结束时对Lob对象进行关闭。

TransactionSynchronizationManager与图2中SuspendedResourceHolder具有对应的属性,前者是保存当前事务的执行上下文;后者则是被暂停的外部事务的执行上下文,当前事务commit或rollback之后,后者的值就被恢复到TransactionSynchronizationManager。

TransactionSynchronizationManager所有属性都是静态ThreadLocal变量,事务执行过程中所有方法都可以随时读取或修改当前事务的执行上下文。这样设计与事务处理的原子性保持了一致,任何时候都仅仅处于一个最小事务提交之中。

3、适配层

Spring在适配层继承实现AbstractPlatformTransactionManager类等,集成各种访问数据源或者消息中间件的类库,包括:

事务管理器类


小结

Spring事务管理框架简单易用、方便集成,它使得用户可以不用再关注事务处理的繁琐细节,而更专注于业务逻辑。另外,Spring事务管理框架本身的分层设计思想也很值得学习借鉴。


本文作者:孙兆玉,点融FinCore团队资深软件开发工程师,擅长Web后端开发,平时热爱钻研新技术,对分布式计算和数据管理很感兴趣。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容