TransactionProxyFactoryBean声明式事务

<bean id="hibernateTransProxy" abstract="true" lazy-init="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="hibernateTransManager" />
</property>
<property name="transactionAttributes">
<props>
<!-- 
transactionAttributes属性可以设置事务处理的方式,事务隔离级别,是否只读三个属性,用逗号隔开
事务隔离级别各数据库系统不完全支持,一般不设置,用默认的即可
事务处理选项有如下几个:(前面2个常用)
PROPAGATION_REQUIRED  - 需要事务处理。如果当前不存在事务环境,则创建一个
PROPAGATION_SUPPORTS  - 如果当前存在事务环境,则作为其中的一部分。如果不存在,则按非事务方式执行
PROPAGATION_REQUIRES_NEW  - 需要事务处理。并总是开启一个新事务。如果已经存在事务环境,则挂起之
PROPAGATION_MANDATORY  - 执行到指定方法时,必须已经存在事务环境,否则出错
PROPAGATION_NEVER  - 不支持事务操作,如果存在事务环境会出错
PROPAGATION_NOT_SUPPORTED  - 不支持事务操作。如果存在事务,则挂起
-->
<!-- find打头和get打头的方法事务处理方式为PROPAGATION_SUPPORTS,其他的采用PROPAGATION_REQUIRED -->
                <!-- readOnly 表示只读事务 ;-->
                <!-- -Exception 表示发生异常时回滚事务;+Exception 表示即使发生异常事务也不回滚;-->
<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>


</props>
</property>

在使用hibernateTransProxy这个事务控制的时候,遇到的问题:

1.在一个方法执行的时候什么情况下事务会提交,什么情况下事务会回滚;
2.嵌套执行的事务提交和回滚的情况又是什么样子的;
 

org.springframework.transaction.interceptor.TransactionProxyFactoryBean
这个类就是以IOC为基础的面向切面编程的采用动态代理实现的声明式事务
面向切面编程:就是spring的AOP,它的思想就是在方法的调用前和方法的调用后来
做一些操作,包括日志、监控,甚至是改变方法的传入参数的值等;它的作用像管家
或者后勤,为方法的正常执行提供保障。
代理:就是控制,就像中介代理房东卖房子一样,spring替你控制,控制什么,控制bean;对于
TransactionProxyFactoryBean类来说就是控制bean的事务,而且它将事务的原子性
提高到方法这一层,而不是过去的一行代码一个事务;由此类代理的bean的一个方法
是一个事务。
声明式事务:就是说这个是由配置文件来实现的,配置在xml中,所以它是以IOC为基础的。


// ServiceClient没有事务,ServiceDAO有事务,testThrowException
// 抛出异常单独一个事务回滚,save2单独一个事务提交
public void testException() {
int result = 0;
try {
result = service.testThrowException("3", "一月又一月", "33");
} catch (Exception e1) {
e1.printStackTrace();
}
if (result == 1) {
try {
throw new Exception("ddd");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


service.save2("2", "哈asdfas", "33");
service.save2("5", "哈哈哈", "33");
}


// ServiceClient没有事务,ServiceDAO有事务,testTryCatchException
// 捕获异常单独一个事务提交,save2单独一个事务提交
public void testTryCatchException() {
int result = 0;
result = service.testTryCatchException("3", "一月又一月", "33");
if (result == 1) {
try {
throw new Exception("ddd");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


service.save2("2", "哈asdfas", "33");
service.save2("5", "哈哈哈", "33");
}

所以,问题1答案是:一个方法调用捕获异常,已经执行的持久化仍然提交;抛出异常持久化
将被回滚。同时应该注意如果持久化的方法以find和get打头,不管是否抛出异常
事务都不会回滚。


问题2实际上是有关事务的传播性,测试发现和在一个方法中还是不一样的。
   /**
* ServiceDAO有事务 BusinessClient也有事务
*/

// save2 正常执行 save1有异常抛出 ,save1回滚 save2也会滚
public void doWorkA() throws Exception {
service.save2("2", "哈哈哈", "33");


service.save1("1", "哈hhhh哈", "33");
}


// save1 有异常抛出 ,save2 根本执行不到
public void doWorkB() throws Exception {
service.save1("2", "哈哈哈", "33");


service.save2("1", "哈hhhh哈", "33");
}


// save2 正常执行 save1有异常抛出被捕获 ,save1回滚 save2也会滚
public void doWorkC() {


service.save2("1", "哈hhhh哈", "33");
try {
service.save1("2", "哈哈哈", "33");
} catch (Exception e) {
e.printStackTrace();
}
}

// 先是doWorkD1 调用save2 正常执行 而后save1有异常抛出被捕获 ,save1回滚 save2也会滚
public void doWorkD() {
doWorkD1();
try {
service.save1("2", "哈哈哈", "33");
} catch (Exception e) {
e.printStackTrace();
}
}


public void doWorkD1() {
service.save2("1", "哈hhhh哈", "33");
}
问题2的答案是嵌套调用的情况下,只要有异常不管是捕获还是抛出,事务都会被被回滚
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值