Java 事务完成后,我们将对象返回为null
我正在处理正在调用的代码,一个事务接一个事务Java 事务完成后,我们将对象返回为null,java,transactions,java-ee-8,Java,Transactions,Java Ee 8,我正在处理正在调用的代码,一个事务接一个事务 @Asynchronous @TransactionTimeout(value = 12, unit = TimeUnit.HOURS) public void runExport(Long id) { /* * some stuff that takes time */ em.persist(objectTest); manager.runAnotherTransaction(id); } @Asyn
@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,
}
正如您在代码中看到的,第一个事务方法是持久化对象,然后我们通过某种管理器调用另一个方法,第二个事务希望检查以前提交的对象上的一些内容。但正如您可能怀疑的那个样,它不能保存,因为对象在数据库中不存在(在我们请求db之前,第一个事务无法保存它)。当我在找到这个物体之前睡一会儿,一切都很好
这个示例代码非常简单,为了避免这个问题,不传递id而传递对象本身(true?)可能是有意义的,但我有一个问题。但我想听听关于这种连接事务的方法的另一个想法或优点/缺点(可能还有更多的缺点),就像我在示例中所做的那样。使用em.persist()
您肯定不会提交任何数据。大多数情况下,您甚至不向数据库写入任何数据
在调用EJB方法后,容器会自动提交数据。因此,在runExport
之后,数据将提交。在此之前,容器还将将数据刷新到数据库中
您也可以使用em.flush()
以编程方式执行此操作。但同样,这不会提交您的数据,只需将其写入即可
如果您确实想自己控制事务,则必须使用@TransactionManagement(TransactionManagementType.BEAN)
。接口javax.transaction.UserTransaction
定义了您需要的方法。persist
方法不能保证标识符值将立即分配给持久实例。如果要立即访问持久化实体,可能应该在持久化之后使用save
@Imaguest而不是flush()
。但是整个设计看起来很奇怪。