【发布时间】:2014-01-10 18:06:17
【问题描述】:
我正在使用 GlassFish v2ur1(这是我们公司使用的,我目前无法升级它)。我有一个从计时器定期调用的 EJB (ejbA)。在调用中,我正在读取一个文件,为每一行创建一个实体 bean,并将实体 bean 持久化到一个数据库(PostgreSQL v9.2)。在调用 entitymanager.persist(entityBean) 之后,对 servlet 进行 HTTP 调用,传递 entityBean 的 ID,然后调用另一个 EJB (ejbB)。 ejbB 向另一个实体 bean ejbC 发送 JMS 消息。这是一个生产系统,我必须进行 HTTP 调用,它会进一步处理数据。 ejbC 与 ejbA 在同一个企业应用程序中,但使用不同的 EntityManager。 ejbC接收到id,从db中读取记录,修改记录,持久化。
我遇到的问题是实体 bean 的数据在计时器调用的事务完成之前不会存储到数据库中(见下文)(我知道这是 EJB 的工作方式)。调用 ejbB 时,它无法在 db 中找到具有它接收到的 id 的记录。我尝试了几种方法将数据存储到数据库中,以便 ejbC 可以找到它:
1) 在 ejbA 中持久化 entityBean 时,我尝试将刷新模式设置为 COMMIT:
- em.setFlushMode(FlushModeType.COMMIT)
- instantiate entity bean
- em.persist(entityBean)
- em.flush()
但是,结果是一样的,在调用 ejbC 时,db 中没有记录。
2) 我创建了 ejbD 并在其中添加了一个带有 TransactionAttributeType.REQUIRES_NEW 的 storeRecord 方法(它持久化 entityBean)。这应该暂停 ejbA 的事务,启动 ejbD 的事务,提交它,然后恢复 ejbA 的事务。同样,这里的结果是相同的,在调用 ejbC 时,数据库中没有记录。我还看到此解决方案存在问题,当我调用 storeRecord 方法时,ejbA 调用刚刚停止。没有抛出异常,但即使有更多行,我也看不到 EJB 正在处理文件中的任何行。它似乎中止了 EJB 调用并在没有任何迹象的情况下回滚了事务。不确定这是否是 GlassFish v2ur1 错误。
如何确保数据存储在 ejbA 中的 db 中,以便在调用 ejbC 时,它可以找到 db 中的记录?顺便说一句,ejbA 中还有其他事情我不一定要提交。我想仅将我尝试存储到数据库中的 entityBeans 持久化。
ejbA
ejbTimer called (txn starts)
read file contents
for each line
create entity bean
persist entity bean to db
make HTTP call to ejbB, passing id
<see ejbC>
return (txn ends)
ejbB
Processes data based on id
Looks up JMS queue for ejbC
Passes ejbC the id
ejbC
ejb method called (txn starts)
read record based on received id
modify record and persist
return (txn ends)
【问题讨论】:
标签: java postgresql transactions glassfish ejb