【问题标题】:Seam @Transactional annotation not working?Seam @Transactional 注释不起作用?
【发布时间】:2011-10-26 20:18:46
【问题描述】:

我在接缝组件上使用@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 注释来触发我的方法调用。

【问题讨论】:

    标签: java oracle seam transactional


    【解决方案1】:

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

    我注意到@Transactional 的方法是protected。这对我来说意味着它正在被另一个内部方法调用。

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

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

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

    【讨论】:

    • 我认为你在这里有所收获
    • 接受这一点,因为他真的很接近 Seam 的问题。除非您从一个 Seam 组件转到另一个,否则不会使用 @Transactional 注释。在这种情况下,我们从同一个 Seam 组件 (MyComponent) 中调用 Transactional 方法。通过将对 Transactional 方法的调用拉到另一个组件,TransactionInterceptor 现在被触发,一切都很好。
    • 是的,我以为是这样的。很高兴它有帮助。
    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多