Java JPA使用flush触发异常并停止执行
在最近的一个任务中,在我创建了一个对象之后,我将结果刷新到数据库中。数据库表有一个唯一的约束,这意味着如果我第二次尝试刷新同一条记录,我将得到一个Java JPA使用flush触发异常并停止执行,java,multithreading,jpa,Java,Multithreading,Jpa,在最近的一个任务中,在我创建了一个对象之后,我将结果刷新到数据库中。数据库表有一个唯一的约束,这意味着如果我第二次尝试刷新同一条记录,我将得到一个ConstraintViolationException。下面显示了一个示例代码段: createEntityAndFlush(结果); 发送异步请求到第三个系统(param); createEntityAndFlush的代码: private T createEntityAndFlush(最终T实体)抛出ServiceException{ debu
ConstraintViolationException
。下面显示了一个示例代码段:
createEntityAndFlush(结果);
发送异步请求到第三个系统(param);
createEntityAndFlush的代码:
private T createEntityAndFlush(最终T实体)抛出ServiceException{
debug(“持久化{}”,entity.getClass().getSimpleName());
getEntityManager().persist(实体);
getEntityManager().flush();
返回实体;
}
我使用flush的原因是我想确保在完成事务之前抛出ConstraintViolationException
,从而调用sendAsyncRequestToThirdSystem
。但事实并非如此,因为在抛出异常后调用了sendayncRequestToThirdSystem
为了在比赛条件下测试代码,我使用ManagedExecutorService并创建了两个可运行任务(Future submit(runnable task))
,以复制传入的请求
最终,通过尝试为每个唯一的请求id在新表上执行锁定,问题得到了解决,但我想知道我在第一种方法中的错误之处(例如错误使用flash,ManagedExecutorService导致了笨拙的行为)。提前谢谢 问题在于,虽然
flush()
确实将更改刷新到数据库中,但事务仍然打开,并且当事务提交时,将检查唯一约束(这可能取决于数据库,但至少对于Postgres和任何正在使用的DB)
因此,您需要确保
createEntityAndFlush(结果)
在其自己的事务中运行,可能与@Transactional(propagation=propagation.REQUIRES_NEW)
(或等效的,如果不使用Spring)一起运行,以查看是否违反了唯一索引。问题是当flush()
将更改刷新到数据库中时,事务仍然打开,当事务提交时,将检查唯一约束(这可能取决于数据库,但至少对于Postgres和任何正在使用的DB)
因此,您需要确保createEntityAndFlush(结果)
在它自己的事务中运行,可能与@Transactional(propagation=propagation.REQUIRES_NEW)
(或者等效的,如果不使用Spring)一起运行,以查看是否违反了唯一索引