EJB Transaction属性覆盖方法级别

时间:2014-06-24 05:11:03

标签: java transactions ejb-3.0

我有一个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)注释了它,但为什么呢?

请帮我摆脱这个。

1 个答案:

答案 0 :(得分:3)

这里有两个问题:

a)persist()不是business method。商业方法必须(在其他规则中)公开。

b)您使用简单的对象方法调用调用persist()方法,因此,Container无法管理代码。请记住,@ TransnsAttribute注释需要由Container解释,在这种情况下不会发生。

一种可能的解决方案是使用persist()方法代码创建其他EJB并将其注入MyAction bean。 这样,每次调用persist()方法时,Container都会拦截调用并创建一个新事务。