Spring声明式事务管理(主为解耦,与业务代码解耦 与具体事务管理器解耦)

Spring中的事务管理是通过AOP实现自身功能增强的典型模块,在这个模块中 Spring把在企业应用中事务处理的主要过程抽象出来 并且通过简洁的aop的切面增强实现了声明事务处理的功能 简单的说 我们只需要在IOC容器中对事务属性进行配置即可完成 同时这些事务处理的基本过程和具体的事务处理器实现是无关的 也就是说 应用可以选择不同的具体的事务处理机制  如JTA JDBC  HIBERNATE  因为采取了声明式事务处理(结合aspectJ) 所以这些事务处理机制被纳入spring事务处理的统一框架中 并完全与具体业务代码解耦

还是通过代码来阐述吧:

applicationContext.xml

<!--事务管理DataSourceTransactionManager -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    

//DataSourceTransactionManager类就是JDBC事务管理器 

//这个是可以换成其他事务管理器的 比如 支持分布式事务管理的JTA 再或者hibernate事务管理器等

//如果仅仅看这个事务管理器的话 是完全与业务代码解耦的 具体在什么sql上植入事务 是由下面的配合aspectJ的aop来植入的


<property name="dataSource" ref="defaultDataSource" />
</bean>


<!-- 针对注解声明式的事物 -->
<tx:annotation-driven transaction-manager="txManager" />             

 //<tx:annotation-driven />这个标签仅仅是声明了个针对注解的事务

//真正完成事务管理的是transaction-manager="txManager"   是里面引用的事务管理器 这个才是核心

<aop:config>
<!-- <aop:pointcut id="baseServiceMethods" expression="execution(* com.gwssi.*.service..*.*(..))" 
/> -->
<aop:pointcut id="baseServiceMethods"
expression="target(com.gwssi.optimus.core.service.BaseService)" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="baseServiceMethods" />
</aop:config>


<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="select*" read-only="true" propagation="SUPPORTS"
rollback-for="Exception" />
<tx:method name="find*" read-only="true" propagation="SUPPORTS"
rollback-for="Exception" />
<tx:method name="do*" propagation="REQUIRED" isolation="READ_COMMITTED"
rollback-for="Exception" />
<tx:method name="insert*" propagation="REQUIRED" isolation="READ_COMMITTED"
rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"
rollback-for="Exception" />
<tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"
rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED"
rollback-for="Exception" />
</tx:attributes>
</tx:advice>



JDBC事务的优缺点:

JDBC为使用Java进行数据库的事务操作提供了最基本的支持。通过JDBC事务,我们可以将多个SQL语句放到同一个事务中,保证其ACID特性。JDBC事务的主要优点就是API比较简单,可以实现最基本的事务操作,性能也相对较好。

但是,JDBC事务有一个局限:一个 JDBC 事务不能跨越多个数据库 所以,如果涉及到多数据库的操作或者分布式场景,JDBC事务就无能为力了

所以涉及到了分布式事务的管理器 JTA:

引用网上对JTA的解释

通常,JDBC事务就可以解决数据的一致性等问题,鉴于他用法相对简单,所以很多人关于Java中的事务只知道有JDBC事务,或者有人知道框架中的事务(比如Hibernate、Spring)等。但是,由于JDBC无法实现分布式事务,而如今的分布式场景越来越多,所以,JTA事务就应运而生。

如果,你在工作中没有遇到JDBC事务无法解决的场景,那么只能说你做的项目还都太小。拿电商网站来说,我们一般把一个电商网站横向拆分成商品模块、订单模块、购物车模块、消息模块、支付模块等。然后我们把不同的模块部署到不同的机器上,各个模块之间通过远程服务调用(RPC)等方式进行通信。以一个分布式的系统对外提供服务。

一个支付流程就要和多个模块进行交互,每个模块都部署在不同的机器中,并且每个模块操作的数据库都不一致,这时候就无法使用JDBC来管理事务。

JTA里面提供了 java.transaction.UserTransaction ,里面定义了下面几个方法

JTA的优点很明显,就是提供了分布式事务的解决方案,严格的ACID。但是,标准的JTA方式的事务管理在日常开发中并不常用,因为他有很多缺点:

  • 实现复杂
    • 通常情况下,JTA UserTransaction需要从JNDI获取。这意味着,如果我们使用JTA,就需要同时使用JTA和JNDI。
  • JTA本身就是个笨重的API
  • 通常JTA只能在应用服务器环境下使用,因此使用JTA会限制代码的复用性。

begin:开启一个事务

commit:提交当前事务

rollback:回滚当前事务

setRollbackOnly:把当前事务标记为回滚

setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务

这里,值得注意的是,不是使用了UserTransaction就能把普通的JDBC操作直接转成JTA操作,JTA对DataSource、Connection和Resource 都是有要求的,只有符合XA规范,并且实现了XA规范的相关接口的类才能参与到JTA事务中来,关于XA规范,请看我的另外一篇文章中有相关介绍。这里,提一句,目前主流的数据库都支持XA规范。

XA规范不知道的童鞋请看我的另一篇文章 《XA规范简洁》

下一篇文章我将会介绍一种阿里巴巴的分布式事务管理机制 dubbo分布式事务管理   以及用法 请关注。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值