`
springoflove
  • 浏览: 2332 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

关于Spring 嵌套事务 PROPAGATION_NEW的问题

阅读更多
看了 解惑 spring 嵌套事务 http://www.iteye.com/topic/35907?page=1真是受益匪浅啊。不过再测试的时候发现个问题:
ServiceA {   
       
    /**  
     * 事务属性配置为 PROPAGATION_REQUIRED  
     */  
    void methodA() {   
        ServiceB.methodB();  
        methodC(); 
    }   

   /**  
     * 事务属性配置为 PROPAGATION_NEW  
     */    
    void methodC() {   
    }   
  
}   
  
ServiceB {   
       
    /**  
     * 事务属性配置为 PROPAGATION_NEW  
     */    
    void methodB() {   
    }   
       
}  

引用

PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)


在执行ServiceA.methodA()的时候执行到ServiceB.methodB() 就会挂起当前事务,新建一事务。但是执行到methodC()的时候通过spring的日志我发现methodC只是使用了当前的事务,而并未新建一个事务。对于这个问题感觉比较疑惑,不知道spring的官方文档上有没有提到。我测试的spring的版本是2.03,2.07,2.52。
分享到:
评论
13 楼 springoflove 2009-04-21  
96sd2 写道
如果在同一个service里面有methodA要调用methodC,又要在同一个事务里面,改怎么写代码呢?


上面的回复中已经有了,在同一个service中methodA调用methodC,视为内部调用。所以将methodA 事务属性配置为 PROPAGATION_REQUIRED即可。
12 楼 96sd2 2009-04-20  
如果在同一个service里面有methodA要调用methodC,又要在同一个事务里面,改怎么写代码呢?
11 楼 狂放不羁 2008-11-27  
Aop确实无法拦截。因为你的methodC是target 对象上的方法,不是代理对象上的方法。
10 楼 dakulaliu 2008-11-13  
daquan198163 写道
你直接调用methodC(),AOP无法拦截啊
投你个新手,哈哈

貌似也可以拦截,只不过得用AspectJ了
9 楼 java55 2008-08-08  
我也是个新手,正在看spring源码,有兴趣可以一起讨论下,QQ:78986606
对你这个问题我的理解是:
你在方法里面调用你配了事务属性(PROPAGATION_NEW)的方法,这种方式调用的方法是不会被动态代理的,那么肯定也就不会被TransactionInterceptor拦截了,那自然也就不会创建一个新事务了,
8 楼 dakulaliu 2008-08-07  
Readonly 写道
methodC是在methodA内被调用的,会被视为一个内部调用,这种情况下AOP不会在methodC上起作用,你需要先看看spring关于aop的文档。
严重同意
7 楼 zhangguoli1997 2008-06-04  
朋友,你JTA用的是那个是JOTM吗!我用JOTM的时候。程序执行完毕没有结束,一直停在那!我是在main函数里调用spring的service的。按常规指向完后程序应该结束!可是没有一直在那等待着!不知道为什么!
下边是执行后的日志!不知道为什么!大家讨论一下!
DEBUG 14:08:58 (Logger.java:37) - StandardXADataSource:getConnection return connection associated with a given XID    
DEBUG 14:08:58 (Logger.java:37) - StandardXAConnection:commit case(state)    
DEBUG 14:08:58 (Logger.java:37) - StandardXAConnection:commit try to commit a connection (STATUS_ACTIVE)    
DEBUG 14:08:58 (Logger.java:37) - StandardXAConnection:commit commit is ok    
DEBUG 14:08:58 (Logger.java:37) - StandardXAConnection:commit setAutoCommit to 'true'    
DEBUG 14:08:58 (Logger.java:37) - StandardXADataSource:freeConnection    
DEBUG 14:08:58 (Logger.java:37) - StandardXADataSource:freeConnection remove id from xidConnections    
DEBUG 14:08:58 (Logger.java:37) - StandardXAStatefulConnection:setState Stateful connection: 1 (state before=0)    
DEBUG 14:08:58 (Logger.java:37) - StandardXAStatefulConnection:setState Stateful connection: 1 (state after=6)    
DEBUG 14:08:58 (SubCoordinator.java:1551) - doAfterCompletion()    
DEBUG 14:08:58 (SubCoordinator.java:1558) - sychronization list size= 1    
DEBUG 14:08:58 (SubCoordinator.java:1565) - Synchronization sync= org.hibernate.transaction.CacheSynchronization    
DEBUG 14:08:58 (SubCoordinator.java:1566) - sync.afterCompletion status= STATUS_COMMITTED    
DEBUG 14:08:58 (CacheSynchronization.java:68) - transaction after completion callback, status: 3    
DEBUG 14:08:58 (JDBCContext.java:283) - after transaction completion    
DEBUG 14:08:58 (SessionImpl.java:403) - after transaction completion    
DEBUG 14:08:58 (Current.java:1275) - threadTx.set = null    
DEBUG 14:08:58 (Current.java:1988) - remove tx from xid (xid=bb14:38:0:01938febbcf9084673...9da401:)    
DEBUG 14:08:58 (SubCoordinator.java:1580) - SubCoordinator unexported [subcoord=org.objectweb.jotm.SubCoordinator@b3319f]    
DEBUG 14:08:58 (Current.java:499) - threadTx.set= null    
DEBUG 14:08:58 (Current.java:500) - reset timeout= 60    
DEBUG 14:08:58 (AbstractPlatformTransactionManager.java:697) - Triggering afterCompletion synchronization    
DEBUG 14:08:58 (TransactionSynchronizationManager.java:265) - Clearing transaction synchronization    
DEBUG 14:09:55 (ConnectionManager.java:369) - running Session.finalize()    
DEBUG 14:09:55 (ConnectionManager.java:369) - running Session.finalize()    
DEBUG 14:23:49 (Logger.java:37) - GenericPool:cleanUp clean up the pool    
DEBUG 14:23:49 (Logger.java:37) - GenericPool:cleanUp clean up the pool    
DEBUG 14:23:49 (Logger.java:37) - GenericPool:cleanUp killing an object    
DEBUG 14:23:49 (Logger.java:37) - StandardPoolDataSource:expire expire a connection, remove from the pool    
DEBUG 14:23:49 (Logger.java:37) - StandardXAConnection:close the XAConnection    
DEBUG 14:23:49 (Logger.java:37) - StandardXADataSource:connectionClosed    
DEBUG 14:23:49 (Logger.java:37) - StandardPoolDataSource:expire close the connection    
DEBUG 14:23:49 (Logger.java:37) - GenericPool:cleanUp killing an object    
DEBUG 14:23:49 (Logger.java:37) - StandardPoolDataSource:expire expire a connection, remove from the pool    
DEBUG 14:23:49 (Logger.java:37) - StandardXAConnection:close the XAConnection    
DEBUG 14:23:49 (Logger.java:37) - StandardXADataSource:connectionClosed    
DEBUG 14:23:49 (Logger.java:37) - StandardXADataSource:connectionClosed close any free connections    
DEBUG 14:23:49 (Logger.java:37) - StandardPoolDataSource:expire close the connection    
INFO 14:23:49 (Logger.java:43) - GenericPool:cleanUp less than minSize objects in the pool min=2 max=50 count=0    
DEBUG 14:23:49 (Logger.java:37) - StandardXADataSource:getXAConnection(user, password)    
DEBUG 14:23:49 (Logger.java:37) - StandardDataSource:getConnection Connection from DriverManager is returned    
DEBUG 14:23:49 (Logger.java:37) - StandardXAStatefulConnection created    
DEBUG 14:23:49 (Logger.java:37) - StandardXAConnection created    
DEBUG 14:23:49 (Logger.java:37) - StandardXAPoolDataSource:create create a object for the pool    
DEBUG 14:23:49 (Logger.java:37) - StandardXADataSource:getXAConnection(user, password)    
DEBUG 14:23:49 (Logger.java:37) - StandardDataSource:getConnection Connection from DriverManager is returned    
DEBUG 14:23:49 (Logger.java:37) - StandardXAStatefulConnection created    
DEBUG 14:23:49 (Logger.java:37) - StandardXAConnection created    
DEBUG 14:23:49 (Logger.java:37) - StandardXAPoolDataSource:create create a object for the pool    
INFO 14:23:49 (Logger.java:43) - GenericPool:cleanUp done min=2 max=50 count=2    
DEBUG 14:33:49 (Logger.java:37) - GenericPool:cleanUp clean up the pool    
DEBUG 14:33:49 (Logger.java:37) - GenericPool:cleanUp clean up the pool    
DEBUG 14:33:49 (Logger.java:37) - GenericPool:cleanUp killing an object    
DEBUG 14:33:49 (Logger.java:37) - StandardPoolDataSource:expire expire a connection, remove from the pool    
DEBUG 14:33:49 (Logger.java:37) - StandardXAConnection:close the XAConnection    
DEBUG 14:33:49 (Logger.java:37) - StandardXADataSource:connectionClosed    
DEBUG 14:33:49 (Logger.java:37) - StandardPoolDataSource:expire close the connection    
DEBUG 14:33:49 (Logger.java:37) - GenericPool:cleanUp killing an object    
DEBUG 14:33:49 (Logger.java:37) - StandardPoolDataSource:expire expire a connection, remove from the pool    
DEBUG 14:33:49 (Logger.java:37) - StandardXAConnection:close the XAConnection    
DEBUG 14:33:49 (Logger.java:37) - StandardXADataSource:connectionClosed    
DEBUG 14:33:49 (Logger.java:37) - StandardPoolDataSource:expire close the connection    
INFO 14:33:49 (Logger.java:43) - GenericPool:cleanUp less than minSize objects in the pool min=2 max=50 count=0    
DEBUG 14:33:49 (Logger.java:37) - StandardXADataSource:getXAConnection(user, password)    
DEBUG 14:33:50 (Logger.java:37) - StandardDataSource:getConnection Connection from DriverManager is returned    
DEBUG 14:33:50 (Logger.java:37) - StandardXAStatefulConnection created    
DEBUG 14:33:50 (Logger.java:37) - StandardXAConnection created    
DEBUG 14:33:50 (Logger.java:37) - StandardXAPoolDataSource:create create a object for the pool    
DEBUG 14:33:50 (Logger.java:37) - StandardXADataSource:getXAConnection(user, password)    
DEBUG 14:33:50 (Logger.java:37) - StandardDataSource:getConnection Connection from DriverManager is returned    
DEBUG 14:33:50 (Logger.java:37) - StandardXAStatefulConnection created    
DEBUG 14:33:50 (Logger.java:37) - StandardXAConnection created    
DEBUG 14:33:50 (Logger.java:37) - StandardXAPoolDataSource:create create a object for the pool    
INFO 14:33:50 (Logger.java:43) - GenericPool:cleanUp done min=2 max=50 count=2  
6 楼 taupo 2008-06-03  
daquan198163 写道
你直接调用methodC(),AOP无法拦截啊
投你个新手,哈哈

一句话点醒了梦中人啊

我也在思考这个问题,,搞了一个通宵都没有高清为什么。。呵呵,谢谢,谢谢

不过,我有句话要说。。。我们可能是菜鸟,但是大家都是从菜鸟过来的,希望大佬们帮帮忙,遇到新手提问就算投了新手贴的同时也回答一下我们的问题,我就有2个新手贴。   ,被扣了很多分,但是没有得到答案,现在还没有能搞清楚
5 楼 Readonly 2008-05-30  
methodC是在methodA内被调用的,会被视为一个内部调用,这种情况下AOP不会在methodC上起作用,你需要先看看spring关于aop的文档。
4 楼 springoflove 2008-05-30  
daquan198163 写道
你直接调用methodC(),AOP无法拦截啊
投你个新手,哈哈

这位大佬可能没仔细阅读我发的问题吧。methodC()我已经在配置文件里配置成PROPAGATION_NEW了,直接调用AOP是可以拦截。
我确实是个新手,从知道什么是硬盘里的A,C,D盘到现在也不到4年的时间,从接触java到今天也不过2年(误差在2天之内) 
3 楼 springoflove 2008-05-30  
Readonly 写道
methodA和methodC同在ServiceA里,所以没有起作用,你可以将methodC移动到另外一个service里面来测试一下就明白了。

我的问题就是为什么在同一个ServiceA里PROPAGATION_NEW就不起作用?
把methodC移动到另一个service里当然可以了,这个我知道。ServiceB的methodB就是与methodC做比较的。
可能是我没叙述清楚吧。。。
2 楼 daquan198163 2008-05-29  
你直接调用methodC(),AOP无法拦截啊
投你个新手,哈哈
1 楼 Readonly 2008-05-29  
methodA和methodC同在ServiceA里,所以没有起作用,你可以将methodC移动到另外一个service里面来测试一下就明白了。

相关推荐

Global site tag (gtag.js) - Google Analytics