0 0

Spring事务传播性问题 —— PROPAGATION_REQUIRES_NEW5

    Spring遇到嵌套事务时,当被嵌套的事务被定义为“PROPAGATION_REQUIRES_NEW”时,内层Service方法被调用时,外层方法的事务被挂起,内层事务相对于外层事务是完全独立的,有独立的隔离性等等...Spring书上如是说的。但我在做一个实验时却遇到一个奇怪的问题,
    1、当一个Service类中的某方法调用另一个Service类中某方法时,内层事务提交也好,回滚也好,都不受外层事务提交或回滚的影响。就是如果内层事务提交了,即使外层事务回滚了,内层事务提交了的数据也不会回归回来了。
    2、当一个Service方法调用本Service类中的另一个方法时,内层事务貌似不能正确地提交或者回滚。

我的代码如下:
BbtForumImpl中在第8行调用BbtForumImpl自己的另一个方法,形成内嵌事务,这样的内嵌事务貌似不能如“PROPAGATION_REQUIRES_NEW”所愿那样工作。而第9行则调用另一个Service类BbtForum2Impl的bankBusiness3()方法,“PROPAGATION_REQUIRES_NEW”工作了,为什么当调用同一个Service类中的其他方法形成嵌套事务时,“PROPAGATION_REQUIRES_NEW”并不如所愿的使外层事务挂起,内层事务独立工作?而调用其它Service类的方法时内层可以独立工作了??????????????????


Serivce类 BbtForumImpl:
1) public void bankBusiness1() throws Exception
2) {
3) AgriculturalBank agriculturalBank = new AgriculturalBank();
4) agriculturalBank.setId("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
5) agriculturalBank.setMoney(new Long(0));
6) agriculturalBankDAOImpl.updateAgriculturalBank(agriculturalBank);
7)
8) this.bankBusiness2();
9)// bbtForum2.bankBusiness3();
10) throw new Exception();
11) }
12)
13) public void bankBusiness2() throws Exception
14) {
15) CommercialBank commercialBank = new CommercialBank();
16) commercialBank.setId("ccccccccccccccccccccccccccccccc");
17) commercialBank.setMoney(new Long(0));
18) commercialBankDAOImpl.updateAgriculturalBank(commercialBank);
19)
20) }


Serivce类 BbtForum2Impl:
1) public void bankBusiness3() throws Exception
2) {
3) CommercialBank commercialBank = new CommercialBank();
4) commercialBank.setId("ccccccccccccccccccccccccccccccc");
5) commercialBank.setMoney(new Long(0));
6) commercialBankDAOImpl.updateAgriculturalBank(commercialBank);
7) }


<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
</bean>

<bean id="bbtForumTarget" class="com.baobaotao.service.impl.BbtForumImpl">
<property name="commercialBankDAOImpl" ref="commercialBankDAOImpl"/>
<property name="agriculturalBankDAOImpl" ref="agriculturalBankDAOImpl"></property>
<property name="bbtForum2" ref="bbtForum2"></property>
</bean>
<bean id="bbtForum" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager"/>
<property name="target" ref="bbtForumTarget"></property>
<property name="transactionAttributes">
<props>
<prop key="bankBusiness">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="bankBusiness1">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="bankBusiness2">PROPAGATION_REQUIRES_NEW, -Exception</prop>
</props>
</property>
</bean>
<bean id="bbtForum2Target" class="com.baobaotao.service.impl.BbtForum2Impl">
<property name="commercialBankDAOImpl" ref="commercialBankDAOImpl"/>
</bean>
<bean id="bbtForum2" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager"/>
<property name="target" ref="bbtForum2Target"></property>
<property name="transactionAttributes">
<props>
<prop key="bankBusiness3">PROPAGATION_REQUIRES_NEW, -Exception</prop>
</props>
</property>
</bean>
2008年11月17日 22:59

1个答案 按时间排序 按投票排序

0 0

PROPAGATION_REQUIRED
加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务
比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候,ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA
的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚


PROPAGATION_REQUIRES_NEW
那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,
他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在
两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,
如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。

2008年11月18日 09:20

相关推荐

    spring 事务传播 demo

    4. **PROPAGATION_REQUIRES_NEW**:总是启动一个新的事务,如果当前存在事务,则将当前事务挂起。 5. **PROPAGATION_NOT_SUPPORTED**:总是以非事务方式执行,如果当前存在事务,则将当前事务挂起。 6. **...

    Spring中事务的传播属性详解

    4. **PROPAGATION_REQUIRES_NEW**:无论当前是否存在事务,都创建一个新的事务,并挂起当前事务。 5. **PROPAGATION_NOT_SUPPORTED**:以非事务方式执行操作;如果当前存在事务,则挂起当前事务。 6. **PROPAGATION_...

    Spring事务传播特性解析

    2、Propagation.REQUIRES_NEW 无论何时自身都会开启事务 3、Propagation.SUPPORTS 自身不会开启事务,在事务范围内则使用相同事务,否则不使用事务 4、Propagation.NOT_SUPPORTED 自身不会开启事务,...

    Spring事务传播Demo.zip

    例如,一个PROPAGATION_REQUIRED的方法调用了一个PROPAGATION_REQUIRES_NEW的方法,那么第二个方法将在新的独立事务中执行,即使第一个方法已经在一个事务中。 SSH,通常指的是Spring、Struts和Hibernate三个开源...

    Spring事务传播属性

    例如,PROPAGATION_REQUIRED适合大部分需要事务控制的操作,而PROPAGATION_REQUIRES_NEW常用于需要独立事务环境的操作,比如发邮件、记录日志等。PROPAGATION_NESTED则用于需要部分独立事务的场景,它允许在保持现有...

    spring 事务传播

    例如,假设`ServiceA.methodA()`的事务传播行为被设置为`PROPAGATION_REQUIRED`,当它调用`ServiceB.methodB()`时(假设`methodB`同样设置了`PROPAGATION_REQUIRED`),如果`methodA`已经处于一个事务中,那么`...

    Spring事务传播原理及数据库事务操作原理.rar

    Spring定义了七种事务传播行为:PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_NEW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER和PROPAGATION_NESTED。每种行为都...

    spring事务的传播特性和事务隔离级别

    Spring提供了七种事务传播特性,每一种都有其特定的场景适用性。 1. **PROPAGATION_REQUIRED** - 这是最常用的传播行为。当使用此传播行为时,如果当前存在事务,则在该事务中执行;如果没有,则创建一个新的事务...

    spring事务隔离级别

    - **PROPAGATION_NESTED**:类似于`PROPAGATION_REQUIRES_NEW`,但在事务内部创建的是一个嵌套事务。如果嵌套事务失败,仅影响嵌套事务本身,外部事务可以继续执行或选择回滚。 #### 五、配置事务隔离级别 在...

    Spring事务原理、Spring事务配置的五种方式

    PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER--以非事务方式执行,如果...

    spring事务传播

    Spring 事务传播是Spring框架中事务管理的重要特性,它定义了在不同事务边界之间如何处理事务的方法调用。Spring 在 `TransactionDefinition` 接口中定义了七种事务传播行为,每种行为都针对不同的业务场景提供了...

    SPRING事务传播特性&事务隔离级别

    4. **PROPAGATION_REQUIRES_NEW** - **定义**:无论当前是否存在事务,都创建一个新的事务。 - **应用场景**:适用于需要独立于外部事务执行的操作。 - **示例**:即使存在`Transaction1`事务,在`Transaction1`...

    Spring事务传播机制.docx

    4. **PROPAGATION_REQUIRES_NEW**:始终创建新的事务,如果当前存在事务,则将当前事务挂起。 5. **PROPAGATION_NOT_SUPPORTED**:不支持事务,如果当前存在事务,则将事务挂起。 6. **PROPAGATION_NEVER**:不...

    Spring事务的传播特性和隔离级别

    4. **Propagation_Requires_New**:总是启动一个新的事务,如果当前存在事务,则将当前事务挂起。适用于需要在独立事务上下文中执行的方法。 5. **Propagation_Not_Supported**:总是以非事务方式执行,并挂起任何...

    这一次搞懂Spring事务是如何传播的

    4. **PROPAGATION_REQUIRES_NEW**:总是创建一个新的事务,如果当前存在事务,则把当前事务挂起。 5. **PROPAGATION_NOT_SUPPORTED**:总是非事务性执行,如果当前存在事务,则把当前事务挂起。 6. **PROPAGATION_...

    事务传播特性了解事务的几种传播特性

    - **PROPAGATION_REQUIRES_NEW**:此行为总是创建一个新的事务来执行当前方法,即使当前已经存在事务,也会挂起当前事务并创建一个新的事务。这种方式适用于那些需要独立事务的操作,即使它们被调用在一个更大的事务...

    Spring在Transaction事务传播行为种类

    PROPAGATION_REQUIRES_NEW - **描述**:总是创建新的事务,如果当前存在事务,则挂起当前事务并创建一个新的事务。 - **适用场景**:适用于需要在新事务中独立完成的操作,即使它被包含在一个更大的事务中。 #####...

    spring基础学习介绍

    例如,PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED的区别在于前者创建完全独立的新事务,而后者创建的是依赖于外部事务的子事务。在PROPAGATION_NESTED中,子事务的提交或回滚与外部事务紧密关联。 另外,当...

    Spring事务管理配置

    - `PROPAGATION_REQUIRES_NEW`:无论当前是否存在事务,都创建一个新的事务,如果有,则将旧事务挂起。 - `PROPAGATION_NOT_SUPPORTED`:以非事务方式执行操作,如果当前存在事务,则挂起该事务。 - `PROPAGATION_...

    事务传播特性&事务隔离级别

    4. PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。 5. PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。 6. PROPAGATION_NEVER:总是非...

Global site tag (gtag.js) - Google Analytics