0

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

  • 数据库查找 (1) 完成后关闭实体管理器
  • 收到外部系统响应后,使用 EntityManagerFactory 创建一个新的实体管理器

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

提前致谢

容器:WebLogic Server 10.3.3

数据库代码:

@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();
            }
        }
    }
}
4

1 回答 1

0

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

于 2013-02-05T09:09:59.587 回答