【问题标题】:JPA duplicate entity creation issueJPA 重复实体创建问题
【发布时间】:2014-02-26 02:57:21
【问题描述】:

我实现了一个 ejb3 无状态会话 bean 来将一组收件人导入数据库。我在公共方法中使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 提交了每个收件人记录

 @Stateless
 @Local(ImportRecipientManagerLocal.class)
 @SecurityDomain("recipient")

 public class ImportRecipientManagerSLB implements ImportRecipientManagerLocal {

 @EJB
 private ImportRecipientManagerLocal anotherRecipientManager;

 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
 @TransactionTimeout(30 * 60)
 @Override
 public RecipientImportStatus saveRecipient(Recipient recipient) throws 
 ImportRecipientFailedException  {
       // saves the reicpient
  }


 public  RecipientsImportStatus createRecipients(List<Recipient> recipientList) {

 // while recipient exist in list
    anotherRecipientManager.saveRecipient(recipient);  
 // end while

}

问题是当客户同时提交了 2 个相同的文件(内容相同)时,它创建了重复的收件人。我认为这是因为两个会话 bean 处理器是并行执行的。但困扰我的是,由于 saveRecipient 结束,事务已提交,数据应该对其他事务可见。不是吗?

我不明白它是怎么发生的,如果有人可以帮助我,不胜感激。

【问题讨论】:

  • REQUIRES_NEW 创建一个新事务并挂起处于活动状态的事务。新事务不属于现有事务的上下文。只有当新事务结束(提交或回滚)时,才会恢复另一个事务。这是您期望的行为吗?
  • 嗨helderdarocha,在这种情况下有两个并行事务正在运行,因为正如我提到的,记录是同时导入的。我认为是第二个过程中的事务,应该看到第一个过程的事务中所做的更改,因为事务是在方法 saveRecipient 结束时提交的

标签: jpa ejb-3.0


【解决方案1】:

正如您所说,如果事务同时并行运行,它会创建重复的收件人,但是如果我们使用 FlushMode.COMMIT 这意味着它总是在提交之前与数据库同步,这就是为什么第二个进程记录插入失败并违反约束的原因。因此,始终建议在提交之前刷新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-03
    • 2018-04-13
    • 2013-08-30
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    相关资源
    最近更新 更多