java - 在方法完成之前未写入 DB 上的 JPA 更改
问题描述
我有一个@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()
在一个线程中,它不再起作用。
但是我认为真正的问题是merge
只有在方法完成后才会更新实体。如何立即更改 Object 的值?
编辑:
@PersistanceContext
private EntityManager em;
mergeUser(T entity){
em.merge(entity);
em.flush();
}
解决方案
根据实际业务需求,可能的解决方案是将otherBlockingOperation()
方法移动到新@Stateless
bean 并将方法标记为@Asynchronous @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
. 这将有效地在新线程和新事务中运行该方法。您只需@Inject
新建 bean 并调用该otherBlockingOperation()
方法。
新事务可能(也可能不是)是有效选项,这取决于业务需求(即新事务可能失败,而原始事务可能成功)。但是,更新将更快地提交到数据库中(但仍然在提交原始事务之后),而不依赖于otherBlockingOperation()
进程(甚至成功提交)。
推荐阅读
- r - 在 rmarkdown 中使用 htmlwidgets 和revealjs
- spring - Spring Boot 2,分离 AuthorizationServer 和 ResourceServer
- php - 我应该将我的 php.ini 文件配置设置为什么,以激活 mail() 功能并将 gmail 用作 smtp 服务器?
- c++ - C ++移动没有右值引用的构造函数?
- c# - Xamarin Azure AD B2C 登录,卡在登录页面
- gitlab - Gitlab-CI(gitlab.com下)“系统故障”启动容器进程
- python - 如何为 django 简单历史表设置 manage=False
- spring-boot - Spring Boot Cassandra Reactive WriteTimeOutException 问题
- node.js - 如何更新文档中的多个数组?
- python - 用一个键将两个元组转换为 Dict:多个值