2010-10-01 33 views
4

我使用Spring 2.5的事务管理和我有以下设置:与Spring控制来自外部事务内部事务设置2.5

Bean1

@Transactional(noRollbackFor = { Exception.class }) 
public void execute() { 
    try { 
    bean2.execute(); 
    } catch (Exception e) { 
    // persist failure in database (so the transaction shouldn't fail) 
    // the exception is not re-thrown 
    } 
} 

Bean2

@Transactional 
public void execute() { 
    // do something which throws a RuntimeException 
} 

失败永远不会从Bean1持久到DB中,因为整个事务被回滚。

我不想在Bean2中添加noRollbackFor,因为它在很多没有逻辑来正确处理运行时异常的地方使用。

有没有一种方法可以避免只有在从Bean1调用Bean2.execute()时才能回滚事务?

否则,我想我最好的选择是坚持我的失败在一个新的交易?还有什么我可以干的?

+0

我不明白为什么它回滚。你是否在catch块中重新抛出异常? – skaffman 2010-10-02 10:23:15

+0

不,我不知道。看起来它正在回滚,因为Spring TransactionInterceptor在退出Bean2时标记了回滚事务。 – Damien 2010-10-02 18:47:26

+0

我使用REQUIRES_NEW传播,通过在新事务中保持失败来解决我的问题。但我很想知道是否有更好的解决方案。 – Damien 2010-10-07 14:36:51

回答

1

这是注释的注意事项之一......您的课程不可重复使用!

如果你想用XML配置事务,如果可能的话。

假设您使用XML配置:如果它不消耗昂贵的资源,则可以创建另一个bean2实例以使用您指定的代码。也就是说,您可以像上面指定的那样配置一个,并且没有任何异常回滚。

+0

谢谢,这是一个很好的评论。无论如何,我的应用程序中的整个交易设置非常糟糕,交易在DAO级别进行了声明。正因为如此,我仍然有一些像问题中所示的嵌入式事务,但当我有机会时,我会尝试重构。 – Damien 2010-10-22 23:04:47