我在类似于:
的接缝组件上使用@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实体,然后出现了抛出异常的错误。我注意到Exception没有导致事务被回滚(修改后的实体仍在db中被修改)所以我添加了“事务活动”日志记录。执行此代码时,isActive()将返回false。
有什么我想念的吗?为什么交易不活跃?
如果它很重要,我正在使用另一个使用RESTEasy注释的组件中的Seam组件来触发我的方法调用。
答案 0 :(得分:6)
我不熟悉Seam的工作方式,所以如果这个答案不适用,我会提前道歉。
我注意到@Transactional
的方法是protected
。这意味着我正在通过另一种内部方法调用它。
使用Spring的AOP,您可以使用@Transactional
标记 public 方法,这些方法将被包装并替换为事务代理。当外部类调用public
方法时,它正在调用构成事务的代理。如果外部类调用不标记为public
的另一个@Transactional
方法然后调用内部方法,那么将不会创建任何事务,因为代理不是完全被召唤。
在Spring中,即使您将doWork()
方法更改为公开,也会出现同样的问题。没有事务,因为没有调用代理对象。在类内部进行的方法调用不会调用代理对象。
快速阅读一些文档似乎表明,像Spring AOP一样,Seam正在使用CGLib proxying。问题是它是否能够代理所有方法 - 即使它们是从代理对象中调用的。很抱歉,如果这个答案不适用,就会浪费你的时间。