我有一个CDI会话作用域操作类,我也在制作一个有状态EJB,用于在整个会话生命周期中保存对象状态。
由于动作类是EJB,因此默认情况下所有方法都是事务性的,我有意不想这样做。我只想要一个action类的单个方法将是transactional,我将只执行数据库持久化任务。所以我使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)注释该单个方法。 Action类使用@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)进行注释。
当我从同一动作类的其他处理程序方法调用事务方法时,没有事务开始。
以下是代码示例。
@Stateful
@Named
@ConversationScoped
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyAction implements Serializable {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
........
........
........
public String handlerMethod1() {
// do some staffs.
persist();
return "view";
}
public String handlerMethod2() {
// do some staffs.
persist();
}
.......
.......
.......
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void persist() {
// save objects.
em.flush();
}
}
调用persist()方法时没有事务开始,虽然我已经用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)注释了它,但为什么呢?
请帮我摆脱这个。
答案 0 :(得分:3)
这里有两个问题:
a)persist()不是business method。商业方法必须(在其他规则中)公开。
b)您使用简单的对象方法调用调用persist()方法,因此,Container无法管理代码。请记住,@ TransnsAttribute注释需要由Container解释,在这种情况下不会发生。
一种可能的解决方案是使用persist()方法代码创建其他EJB并将其注入MyAction bean。 这样,每次调用persist()方法时,Container都会拦截调用并创建一个新事务。