我正在编写正在调用的代码,一个又一个事务。
@Asynchronous
@TransactionTimeout(value = 12, unit = TimeUnit.HOURS)
public void runExport(Long id) {
/*
* some stuff that takes time
*/
em.persist(objectTest);
manager.runAnotherTransaction(id);
}
@Asynchronous
@TransactionTimeout(value = 1, unit = TimeUnit.HOURS)
public void runCopy(Long id) {
if(manager.isPreviousValueCommited(id)){
//do some stuff
}
/*
* some stuff that takes time
*/
}
//other class
public void runAnotherTransaction(long id){
//...
superBean.runCopy(id);
}
public void isPreviousValueCommited(long id){
//Thread.sleep(1000) if we sleep here, object wont be null
SomeObject obj = em.find(SomeObject.class, id); //is null,
}
正如您在代码中看到的,第一个事务方法是持久化对象,之后我们通过某种管理器
调用其他方法,第二个事务想要检查先前提交的一些内容目的。但正如您可能怀疑它不能,因为数据库中不存在对象(第一个事务在我们询问数据库之前无法保存它)。当我在找到这个物体之前睡一会儿时,一切都很好。
这个示例代码非常简单,为了避免这个问题,不传递 id,而是传递对象本身(true?)可能是有意义的,但我有疑问。但我想听听这种连接事务的方法的其他想法或优点/缺点(可能还有更多缺点),就像我在示例中所提到的那样。
最佳答案
使用em.persist()
,您绝对不会提交任何数据。大多数时候,您甚至不向数据库写入任何数据。
调用 EJB 方法后,容器会自动提交您的数据。因此,在 runExport
之后,数据将提交。在此之前,容器还将数据刷新
到数据库。
您也可以使用em.flush()
以编程方式执行此操作。但同样,这不会提交您的数据,只是写入它。
如果您确实想自己控制事务,则必须使用@TransactionManagement(TransactionManagementType.BEAN)
。接口(interface)javax.transaction.UserTransaction
定义了您需要的方法。
关于java - 事务完成后,我们将对象返回为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60300070/