`
leopard_lb
  • 浏览: 41577 次
  • 性别: Icon_minigender_1
  • 来自: 太原
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论
阅读更多

spring自建事务管理模块。而且这个事务管理是一个抽象设计,可以应用到很多场合,包括普通的DataSource,jta,jms和hibernate上。

要正确使用spring的事务,首先需要了解spring在事务设计上的一些概念
统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatus

PlatformTransactionManager直译过来就是平台相关事务,这里的平台指的是“事务源”,包括刚才我说的DataSource,jta等等。这些无一不是一个事务源。广义的说,凡是可以完成事务性操作的对象,都可以设计出相对应的PlatformTransactionManager,只要这个事务源支持commit,rollback和getTransaction语意。

查看spring代码,可以发现这些manager实现事务,就是调用事务源的事务操作方法

比如

HibernateTransactionManager

代码
  1. protected void doCommit(DefaultTransactionStatus status) {   
  2.         HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();   
  3.         if (status.isDebug()) {   
  4.             logger.debug("Committing Hibernate transaction on session [" +   
  5.                     txObject.getSessionHolder().getSession() + "]");   
  6.         }   
  7.         try {   
  8.             txObject.getSessionHolder().getTransaction().commit();   
  9.         }   
  10. ...   
  11.   
  12.     }  
<script>render_code();</script>

 

jdbc 的DataSourceTransactionManager

代码
  1. protected void doCommit(DefaultTransactionStatus status) {   
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();   
  3.         Connection con = txObject.getConnectionHolder().getConnection();   
  4.         if (status.isDebug()) {   
  5.             logger.debug("Committing JDBC transaction on connection [" + con + "]");   
  6.         }   
  7.         try {   
  8.             con.commit();   
  9.         }   
  10.         ...   
  11.     }  
<script>render_code();</script>

 

那么PlatformTransactionManager以什么依据处理事务呢?
是TransactionStatus
查看api发现这个接口有三个方法
isNewTransaction() ,isRollbackOnly(),setRollbackOnly()
PlatformTransactionManager就是根据前两个方法决定是否要创建一个新事务,是要递交还是回滚。至于第三个方法是改变事务当前状态的,很多地方都要用到,偏偏PlatformTransactionManager自身好像不怎么用,毕竟事务状态的改变是由程序员代码决定的,不需要一个manager多管闲事。

总结上面所说的,spring的事务由PlatformTransactionManager管理,manager最后调用事务源的方法来实现一个事务过程。而manager通过TransactionStatus 来决定如何实现。

接下去说spring事务中的TransactionTemplate和TransactionInterceptor

TransactionTemplate其实和spring中其他的template的作用类似,起到化简代码的作用,不要被它那么长的名字吓倒了,事实上这个template并不是什么非常核心的对象。如果比较学究派的,可以去看看template设计模式,在此就不再对此赘述了。
为什么要有TransactionTemplate?先来看看如果没有TransactionTemplate,我们的代码该怎么写

先来看看spring reference中的一段代码

代码
  1. DefaultTransactionDefinition def = new DefaultTransactionDefinition()   
  2. def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);   
  3.   
  4. TransactionStatus status = transactionManager.getTransaction(def);   
  5.   
  6. try {   
  7.     // execute your business logic here   
  8. catch (MyException ex) {   
  9.     transactionManager.rollback(status);   
  10.     throw ex;   
  11. }   
  12. transactionManager.commit(status);  
<script>render_code();</script>
这是直接使用transactionManager的例子,可以看到真正执行business logic 的地方是在try当中那段,前后的代码都是为了完成事务管理的。如果每个business logic都要写上那么一段,我肯定是疯了。我们翻出TransactionTemplate的代码看看他怎么化简了我们的代码

 

 

代码
  1. public Object execute(TransactionCallback action) throws TransactionException {   
  2.         TransactionStatus status = this.transactionManager.getTransaction(this);   
  3.         Object result = null;   
  4.         try {   
  5.             result = action.doInTransaction(status);   
  6.         }   
  7.         catch (RuntimeException ex) {   
  8.             // transactional code threw application exception -> rollback   
  9.             rollbackOnException(status, ex);   
  10.             throw ex;   
  11.         }   
  12.         catch (Error err) {   
  13.             // transactional code threw error -> rollback   
  14.             rollbackOnException(status, err);   
  15.             throw err;   
  16.         }   
  17.         this.transactionManager.commit(status);   
  18.         return result;   
  19.     }  
<script>render_code();</script>

 

同上面的代码如出一辙,前后是事务处理代码,当中那段result = action.doInTransaction(status);是我们的应用代码。至于action是什么,全看各位的需要了。但是有一点要主要,如果利用TransactionTemplate,那么他不管你扔出什么异常都会回滚事务,但是回滚的是哪个事务呢?继续挖代码

代码
  1. private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {   
  2.         if (logger.isDebugEnabled()) {   
  3.             logger.debug("Initiating transaction rollback on application exception", ex);   
  4.         }   
  5.         try {   
  6.             this.transactionManager.rollback(status);   
  7.         }   
  8.         catch (RuntimeException ex2) {   
  9.             logger.error("Application exception overridden by rollback exception", ex);   
  10.             throw ex2;   
  11.         }   
  12.         catch (Error err) {   
  13.             logger.error("Application exception overridden by rollback error", ex);   
  14.             throw err;   
  15.         }   
  16.     }  
<script>render_code();</script>
真相大白,是对template所持有的某个transactionManager进行回滚。所以如果你的应用代码用的是事务源a的一些资源,比如到服务器a的一个datasource,但是你的transactionManager管理的是另一些资源,比如服务器b的一个datasource,代码铁定不会正常运行

 

特别是在一些多事务源的程序里,这点千万不能搞错。如果多个事务源之间要完成全局事务,还是老老实实用分布式事务管理服务吧(jta)

那么TransactionInterceptor是干什么的?这个是spring 的声明式事务的支持方式。因为用TransactionTemplate要硬编码,而且调整事务策略很麻烦(不是说不能调。举个例子原来程序抛出异常A需要回滚,现在不需要要,我就可以把a catch吃掉。这时候template就不会回滚了。但是每次调整都要重写编码。)而用TransactionInterceptor就可以将这些调整写在配置中。我们再来挖TransactionInterceptor的代码

 

代码
  1. public Object invoke(MethodInvocation invocation) throws Throwable {   
  2.         // Work out the target class: may be null.   
  3.         // The TransactionAttributeSource should be passed the target class   
  4.         // as well as the method, which may be from an interface   
  5.         Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;   
  6.            
  7.         // Create transaction if necessary   
  8.         TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);   
  9.   
  10.         Object retVal = null;   
  11.         try {   
  12.             // This is an around advice.   
  13.             // Invoke the next interceptor in the chain.   
  14.             // This will normally result in a target object being invoked.   
  15.             retVal = invocation.proceed();   
  16.         }   
  17.         catch (Throwable ex) {   
  18.             // target invocation exception   
  19.             doCloseTransactionAfterThrowing(txInfo, ex);   
  20.             throw ex;   
  21.         }   
  22.         finally {   
  23.             doFinally(txInfo);   
  24.         }   
  25.         doCommitTransactionAfterReturning(txInfo);   
  26.   
  27.         return retVal;   
  28.     }  
<script>render_code();</script>
万变不离其宗。

 

所以使用spring的事务管理需要作这些事
1,设置好事务源,比如DataSource,hibernate的session。如果有多个事务源要考虑他们之间是否有全局事务,如果有,老老实实用jta,否则就需要自己写一个manager了
2,设置manager,根据你的事务源选择对应的PlatformTransactionManager
3,选择实现事物的方式,用template还是interceptor。用template代码直观点,但是template所管辖的manager和你应用代码所用的事务源要一致。如果用interceptor千万注意,一定要调用interceptor那个bean,而不是原始的那个target。在坛子上我已经看到至少有两个朋友说spring事物不起作用,从配置和代码上看都正确,这时要好好查查,调用的bean是哪一个。
4,这个是设计问题了,推荐事务处于一个较高层次,比如service上的某个函数,而底层的dao可以不考虑事务,否则可能会出现事务嵌套,增加程序复杂度。

分享到:
评论

相关推荐

    铅笔头识别数据集,1692张原始训练图,640*640分辨率,91.1%的正确识别率,标注支持coco json格式

    铅笔头识别数据集,1692张原始训练图,640*640分辨率,91.1%的正确识别率,标注支持coco json格式

    高校网络教学的体系规划与创建.docx

    高校网络教学的体系规划与创建.docx

    SpringBoot的学生心理咨询评估系统,你看这篇就够了(附源码)

    SpringBoot的学生心理咨询评估系统,你看这篇就够了(附源码)

    遗传算法优化BP神经网络提升交通流量预测精度的技术实现与应用

    内容概要:本文详细介绍了如何使用遗传算法优化BP神经网络,以提高交通流量预测的准确性。文中首先解释了BP神经网络的基本结构及其局限性,即容易陷入局部最优解的问题。随后,作者展示了遗传算法的工作原理,并将其应用于优化BP神经网络的权重和偏置。通过定义适应度函数、选择、交叉和变异等步骤,实现了对BP神经网络的有效改进。实验结果显示,优化后的BP神经网络在交通流量预测中的精度显著高于传统的BP神经网络,特别是在处理复杂的非线性问题时表现出色。 适用人群:对机器学习、深度学习以及交通流量预测感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要进行精确交通流量预测的应用场景,如智能交通系统、城市规划等领域。主要目标是通过遗传算法优化BP神经网络,解决其易陷入局部最优的问题,从而提高预测精度和稳定性。 其他说明:文中提供了详细的Python代码实现,帮助读者更好地理解和实践这一优化方法。同时,强调了遗传算法在全局搜索方面的优势,以及其与BP神经网络结合所带来的性能提升。此外,还讨论了一些具体的实施技巧,如适应度函数的设计、交叉和变异操作的选择等。 标签1,标签2,标签3,标签4,标签5

    H5U PLC与触摸屏集成框架:总线伺服控制及跨平台移植的最佳实践

    内容概要:本文详细介绍了H5U框架在PLC与触摸屏集成方面的应用,特别是在总线伺服控制和跨平台移植方面。文章首先解析了伺服控制的核心代码,如使能模块和绝对定位指令,强调了标准化控制流程的优势。接着讨论了触摸屏交互,通过直接映射PLC的DB块地址简化了数据处理。然后介绍了总线配置,尤其是EtherCAT总线初始化及其容错设计。此外,文章还探讨了框架的移植性和报警处理设计,展示了其在不同PLC品牌间的易用性和高效的故障恢复能力。 适合人群:从事工业自动化领域的工程师和技术人员,特别是有PLC编程经验和需要进行伺服控制系统开发的人群。 使用场景及目标:①快速搭建和调试基于PLC和触摸屏的自动化控制系统;②提高多轴设备的调试效率;③实现跨平台的无缝移植;④优化报警管理和故障恢复机制。 其他说明:该框架不仅提供了详细的代码示例和注释,还包含了丰富的实战经验和最佳实践,使得新手能够快速上手,而资深工程师可以在此基础上进一步创新。

    游戏开发UE5引擎核心技术解析与应用:涵盖安装配置、项目创建及蓝图编辑器详解文档的主要内容

    内容概要:本文档《UE5开发.txt》全面介绍了Unreal Engine 5(UE5)的基本概念、安装配置、项目创建、文件结构及常用功能。UE5是一款强大的游戏引擎,支持实时渲染、蓝图创作、C++编程等功能。文档详细描述了UE5的安装步骤,包括硬件要求和环境配置;项目创建过程,涵盖项目模板选择、质量预设、光线追踪等设置;文件结构解析,重点介绍了Config、Content和.uproject文件的重要性。此外,文档深入讲解了蓝图编辑器的使用,包括变量、数组、集合、字典等数据类型的操作,以及事件、函数、宏和事件分发器的应用。蓝图作为一种可视化脚本工具,使开发者无需编写C++代码即可快速创建逻辑,适用于快速开发和迭代。 适合人群:具备一定编程基础的游戏开发者、设计师和对游戏开发感兴趣的初学者,尤其是希望深入了解UE5引擎及其蓝图系

    餐馆点菜系统概要设计说明书.doc

    餐馆点菜系统概要设计说明书.doc

    5+1档轿车手动变速箱设计说明书.doc

    5+1档轿车手动变速箱设计说明书.doc

    1万吨自来水厂详细设计说明书.doc

    1万吨自来水厂详细设计说明书.doc

    wordpress外贸电商企业产品主题

    wordpress外贸电商企业产品主题 页面展示图https://i-blink.csdnimg.cn/direct/e45b2e2e8e27423eb79bda5f4c1216d7.png

    低效林改造作业设计说明书.doc

    低效林改造作业设计说明书.doc

    西门子200smart编程软件V2.8.2.1

    西门子200smart编程软件V2.8.2.1

    135调速器操纵手柄 设计说明书.doc

    135调速器操纵手柄 设计说明书.doc

    蓝桥杯全国软件和信息技术专业人才竞赛指导文档.pdf

    内容概要:本文档为蓝桥杯全国软件和信息技术专业人才竞赛提供了全面的指导,涵盖竞赛概述、流程与规则、核心考点与备赛策略、实战技巧与避坑指南以及备赛资源推荐。蓝桥杯竞赛由工信部人才交流中心主办,涉及算法设计、软件开发、嵌入式系统、电子设计等领域。文档详细介绍了参赛流程(报名、省赛、国赛、国际赛),并针对软件类和电子类竞赛分别阐述了高频考点和备赛建议。对于软件类,强调了算法与数据结构的重要性,如排序、动态规划、图论等;对于电子类,则侧重于硬件基础和开发工具的使用。此外,还提供了详细的答题策略、常见陷阱规避方法及工具调试技巧。; 适合人群:高校本专科生、研究生,尤其是对算法设计、软件开发、嵌入式系统等领域感兴趣的计算机科学及相关专业的学生。; 使用场景及目标:①帮助参赛选手熟悉竞赛流程和规则,明确各阶段任务;②提供系统的备赛策略,包括高频考点的学习和专项突破;③指导选手掌握实战技巧,避免常见错误,提高答题效率和准确性。; 阅读建议:此文档不仅提供了理论知识,还包含了大量实战经验和备赛资源推荐,建议读者结合自身情况制定个性化的备赛计划,充分利用提供的资源进行练习和准备。

    基于行块抽取正文内容的java版本的改进算法.zip

    基于行块抽取正文内容的java版本的改进算法.zip

    基于S7-200 PLC和MCGS的快递分拣系统设计与实现:硬件配置、梯形图编程及组态应用

    内容概要:本文详细介绍了基于西门子S7-200 PLC和MCGS组态软件的快递分拣系统的设计与实现方法。首先阐述了硬件配置的关键要点,包括IO分配表的具体设置以及传感器和执行机构的连接方式。接着深入解析了PLC程序中的梯形图逻辑,涵盖主传送带的连锁保护、机械臂动作的自保持逻辑和安全复位机制等核心部分。同时探讨了MCGS组态画面的应用,展示了如何通过脚本实现动态效果和数据统计功能。此外,文中还分享了一些调试经验和常见问题的解决方案,如防止传感器抖动、优化数据传输效率等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC编程和组态软件有一定了解的人群。 使用场景及目标:适用于需要构建高效可靠的快递分拣系统的物流企业或相关项目开发者。目标是帮助读者掌握从硬件选型到软件编程的一整套实施流程,确保系统能够稳定运行并达到预期性能指标。 其他说明:文章不仅提供了理论指导,还结合实际案例进行了详细的步骤讲解,有助于读者更好地理解和应用于实践中。

    joblib-0.12.5-py2.py3-none-any.whl

    该资源为joblib-0.12.5-py2.py3-none-any.whl,欢迎下载使用哦!

    机器学习分类算法实战:基于sklearn的决策树、随机森林与KNN Python实现

    内容概要:本文详细介绍了三种经典的机器学习分类算法——决策树、随机森林和KNN分类器,在Python的sklearn库中的具体实现方法。首先,通过加载鸢尾花数据集进行数据准备,并将其划分为训练集和测试集。接着分别实现了决策树、随机森林和KNN分类器,展示了每种算法的关键参数配置及其对模型性能的影响。对于决策树,重点讨论了max_depth参数的作用以及如何通过可视化工具理解其分裂过程;随机森林部分强调了n_estimators参数的选择和特征重要性的评估;而KNN分类器则着重于特征标准化的重要性和n_neighbors参数的优化。此外,文中还提供了关于模型选择的指导,帮助读者根据不同应用场景选择合适的算法。 适合人群:对机器学习感兴趣的初学者和有一定编程基础的研发人员。 使用场景及目标:①理解并掌握决策树、随机森林和KNN分类器的工作原理;②学会使用sklearn库快速构建和评估分类模型;③能够根据具体问题特点选择最适合的分类算法。 其他说明:本文不仅提供了详细的代码示例,还分享了许多实践经验,如参数调优技巧、模型评估方法等,有助于读者更好地理解和应用这些算法。

    带式输送机传动装置设计课程设计说明书.doc

    带式输送机传动装置设计课程设计说明书.doc

    gh毕业论文 伦潭水利枢纽工程土石坝设计说明书.doc

    gh毕业论文 伦潭水利枢纽工程土石坝设计说明书.doc

Global site tag (gtag.js) - Google Analytics