DB 上的 JPA 更改未在方法完成之前写入
JPA changes on DB not written before method finished
我有一个 @Stateless
-Bean,它以单一方法执行一些数据库操作
public void doOperation(){
User u1 = createNewUser()
User u2 = createNewUser()
User updated = mergeUser(u1,u2) // just as an example
// should write to database now!
otherBlockingOperation()
}
但是,在阻塞操作完成之前,更改在数据库中不可见,因此在前端不可见。
我认为这是因为事务直到 otherBlockingOperation()
完成才提交。然后我将 otherBlockingOperation()
包裹在一个 Thread 中,但它再次不起作用。
但是我认为真正的问题是 merge
它只会在方法完成后更新实体。如何立即更改对象的值?
编辑:
@PersistanceContext
private EntityManager em;
mergeUser(T entity){
em.merge(entity);
em.flush();
}
根据实际业务需求,可能的解决方案是将otherBlockingOperation()
方法移动到新的@Stateless
bean,并将该方法标记为@Asynchronous @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
。这将有效地 运行 新线程和新事务中的方法。您只需 @Inject
新 bean 并调用 otherBlockingOperation()
方法。
新交易可能(或可能不是)是一个有效的选项,这取决于业务需求(即新交易可能会失败,而原始交易可能会成功)。但是,更新将更快地在数据库中提交(但仍在提交原始事务之后),而不依赖于 otherBlockingOperation()
进程(甚至成功提交)。
我有一个 @Stateless
-Bean,它以单一方法执行一些数据库操作
public void doOperation(){
User u1 = createNewUser()
User u2 = createNewUser()
User updated = mergeUser(u1,u2) // just as an example
// should write to database now!
otherBlockingOperation()
}
但是,在阻塞操作完成之前,更改在数据库中不可见,因此在前端不可见。
我认为这是因为事务直到 otherBlockingOperation()
完成才提交。然后我将 otherBlockingOperation()
包裹在一个 Thread 中,但它再次不起作用。
但是我认为真正的问题是 merge
它只会在方法完成后更新实体。如何立即更改对象的值?
编辑:
@PersistanceContext
private EntityManager em;
mergeUser(T entity){
em.merge(entity);
em.flush();
}
根据实际业务需求,可能的解决方案是将otherBlockingOperation()
方法移动到新的@Stateless
bean,并将该方法标记为@Asynchronous @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
。这将有效地 运行 新线程和新事务中的方法。您只需 @Inject
新 bean 并调用 otherBlockingOperation()
方法。
新交易可能(或可能不是)是一个有效的选项,这取决于业务需求(即新交易可能会失败,而原始交易可能会成功)。但是,更新将更快地在数据库中提交(但仍在提交原始事务之后),而不依赖于 otherBlockingOperation()
进程(甚至成功提交)。