CDI 中 @Transactional 的局限性是什么?
What are the limitations of @Transactional in CDI?
我正在尝试在 CDI class 中使用 @Transactional
方法,而不是 EJB:
@javax.inject.Named
// fails @javax.enterprise.context.ApplicationScoped
// fails @javax.enterprise.context.SessionScoped
// works @javax.ejb.Singleton
// works @javax.ejb.Stateless
public class SomeClass {
@javax.persistence.PersistenceContext
private EntityManager em;
@javax.annotation.PostConstruct
@javax.transaction.Transactional
public void someMethod() {
em.persist(someEntity);
}
}
当我用 @Singleton
或 @Stateless
注释 SomeClass
时,一切正常。
当我用 @ApplicationScoped
或 @SessionScoped
注释 SomeClass
时,WildFly 13 显示以下错误消息:
Transaction is required to perform this operation (either use a transaction or extended persistence context)
我的印象是 @Transactional
从 Java EE 7 开始就与 CDI 一起工作。我错了吗?或者我只是缺少一些额外的配置?
我将尝试给出一个简短的清单,列出在尝试使 @Transactional
与 CDI 一起工作时要查看的内容,以便给出比评论更有价值的答案:
- 我们正在讨论
javax.transaction.Transactional
,而不是 javax.ejb.TransactionAttribute
,它适用于 EJB!
- 它不能在非 JEE 应用程序中开箱即用!
- 我们所说的 JEE 应用程序是指 运行 完整的 JEE 应用程序服务器; Tomcat 开箱即用不支持!
- 注意类路径问题,特别要确保不存在包含注释
javax.transaction.Transactional
的 jar,例如在 WEB-INF/lib 中,当 运行 在完整的 JEE 应用程序服务器中。如果你想在非完整的 JEE 环境中使用它,你需要将它放在类路径中。
@Transactional
被最新的JTA规范实现为CDI拦截器。像这样:
- JEE < 7 中没有!
- 它具有与任何拦截器相同的限制。例如。它不能被初始化方法调用 -
@PostConstruct
[这是这个问题中的问题],并且在调用 this
对象的方法时它是 NOT 激活,当心!!!
- 我很有信心可能存在更多错误!!!
我正在尝试在 CDI class 中使用 @Transactional
方法,而不是 EJB:
@javax.inject.Named
// fails @javax.enterprise.context.ApplicationScoped
// fails @javax.enterprise.context.SessionScoped
// works @javax.ejb.Singleton
// works @javax.ejb.Stateless
public class SomeClass {
@javax.persistence.PersistenceContext
private EntityManager em;
@javax.annotation.PostConstruct
@javax.transaction.Transactional
public void someMethod() {
em.persist(someEntity);
}
}
当我用 @Singleton
或 @Stateless
注释 SomeClass
时,一切正常。
当我用 @ApplicationScoped
或 @SessionScoped
注释 SomeClass
时,WildFly 13 显示以下错误消息:
Transaction is required to perform this operation (either use a transaction or extended persistence context)
我的印象是 @Transactional
从 Java EE 7 开始就与 CDI 一起工作。我错了吗?或者我只是缺少一些额外的配置?
我将尝试给出一个简短的清单,列出在尝试使 @Transactional
与 CDI 一起工作时要查看的内容,以便给出比评论更有价值的答案:
- 我们正在讨论
javax.transaction.Transactional
,而不是javax.ejb.TransactionAttribute
,它适用于 EJB! - 它不能在非 JEE 应用程序中开箱即用!
- 我们所说的 JEE 应用程序是指 运行 完整的 JEE 应用程序服务器; Tomcat 开箱即用不支持!
- 注意类路径问题,特别要确保不存在包含注释
javax.transaction.Transactional
的 jar,例如在 WEB-INF/lib 中,当 运行 在完整的 JEE 应用程序服务器中。如果你想在非完整的 JEE 环境中使用它,你需要将它放在类路径中。 @Transactional
被最新的JTA规范实现为CDI拦截器。像这样:- JEE < 7 中没有!
- 它具有与任何拦截器相同的限制。例如。它不能被初始化方法调用 -
@PostConstruct
[这是这个问题中的问题],并且在调用this
对象的方法时它是 NOT 激活,当心!!!
- 我很有信心可能存在更多错误!!!