3

我在接缝组件上使用@Transactional 注释,类似于:

@Name( "myComponent" )
@AutoCreate
public class MyComponent
{
    public void something() {
        ...
        doWork();
    }
    ...
    @Transactional
    protected void doWork() {
        try {
            log.debug( "transaction active: " + Transaction.instance().isActive() );
        } catch (Exception ignore) {}

        // some more stuff here that doesn't appear to be inside a transaction
    }
}

在“一些更多的东西”部分,我正在修改一些 Hibernate 实体,然后遇到了一个引发异常的错误。我注意到异常并没有导致事务回滚(修改后的实体仍在数据库中修改),所以我添加了“事务活动”日志记录。当此代码执行时,isActive() 返回 false。

有什么我想念的吗?为什么交易不活跃?

万一这很重要,我正在使用另一个组件内部的 Seam 组件,该组件使用 RESTEasy 注释来触发我的方法调用。

4

1 回答 1

6

我不熟悉 Seam 的工作原理,所以如果这个答案不适用,我提前道歉。

我注意到方法@Transactionalprotected. 这对我来说意味着它被另一个内部方法调用。

使用 Spring 的 AOP,您可以标记使用事务代理包装和替换的公共方法。@Transactional当外部类调用该public方法时,它正在调用形成事务的代理。如果外部类调用另一个标记的public方法,然后调用内部方法,则不会创建事务,因为根本没有调用代理。@Transactional

在 Spring 中,即使您将doWork()方法更改为 public,也会发生同样的问题。没有事务,因为没有调用代理对象。在类内部进行的方法调用不会调用代理对象。

快速阅读一些文档似乎表明,与 Spring AOP 一样,Seam 正在使用CGLib 代理。问题是它是否能够代理所有方法——即使它们是从代理对象中调用的。如果此答案不适用,抱歉浪费您的时间。

于 2011-10-27T13:55:27.347 回答