是否应该在EJB中关闭JPA实体管理器?

时间:2013-02-05 08:30:11

标签: jpa ejb weblogic

我有以下消息驱动bean,其中首先执行必要的db查找(1),然后调用外部系统(2)(响应时间可以从几秒到2分钟不等),以及之后我更新了一些数据库表(3)。由于我不明白实体经理掌握了哪些资源,我的问题是它是否有意义:

  • 在db lookups(1)完成后关闭实体管理器
  • 在外部使用EntityManagerFactory创建一个新的实体管理器 收到系统回复

此外,我想知道使用EntityManagerFactory.createEntityManager()而不是EntityManager注入是否有优势。

提前致谢

容器:WebLogic Server 10.3.3

MDB代码:

@MessageDriven(
        activationConfig = { @ActivationConfigProperty(
                propertyName = "destinationType", propertyValue = "javax.jms.Queue"
        ) })
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyBean implements MessageListener {

    @Resource
    private MessageDrivenContext context;
    @PersistenceUnit(unitName = "pu1")
    private EntityManagerFactory    emf;

    private static final Logger log = Logger.getLogger(MyBean.class);

    public MyBean() {}

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void onMessage(Message incomingMsg) {
        EntityManager em = null;
        try{
            if(incomingMsg instanceof TextMessage){
                em = this.emf.createEntityManager()
                //perform db lookups (1)
                ...
                em.close()
                //call external system (response time up to 2 min) (2)
                ...
                //db update (3)
                em = this.emf.createEntityManager()
                ...
            } else{
                throw new IllegalArgumentException("Unsupported message type");
            }
        } catch (Exception ex){
            log.error("Message processing failed. Forcing the associated transaction to rollback", ex);
            context.setRollbackOnly();
        } finally{
            if(em != null && em.isOpen()){
                em.close();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

可以让EntityManager保持打开状态(实际上规范说即使你关闭了EntityManager,持久化上下文也会一直打开,直到事务提交或回滚)。您应该担心您的交易,因为如果外部系统调用的响应太慢,它可能会超时。你真的希望这个电话成为交易的一部分吗?这是XA交易吗?否则,您可能需要对代码进行重新分解,以便对外部系统的调用不属于事务的一部分。