Spring Data Jpa + @Async注释方法问题

时间:2018-02-02 22:28:56

标签: hibernate spring-boot asynchronous spring-data-jpa

我有一个spring boot项目,它使用spring jpa存储库来访问数据库。我有一对多的关系(一个AccountRequest,很多国家,AccountRequest有一个States of States字段),而且我经常在该列表中添加新的状态。

当我保存accountRequest时,列表中的所有新状态都会保持不变。

现在,我需要在@Async注释方法中保存一些状态,但是当我这样做时,例如:

@Async()
public void businessMethod(AccountRequest request) {
   saveState(request, "Consulting government policies");
   saveState(request, "Enforcing rules");
   saveState(request, "Process ended successfully");
}

public void saveState(AccountRequest request, String stateDescription) {
   // do stuff
   request.addState(new State(stateDescription));
   // do stuff
   requestRepository.save(request);
}

当businessMethod中的第1行运行时,我得到了下一个行为:

  • 国家“咨询政府政策”持续存在

当businessMethod中的第2行运行时:

  • 国家“咨询政府政策”再次坚持
  • 状态“执行规则”被保留

当businessMethod中的第3行运行时:

  • 国家“咨询政府政策”再次坚持
  • 状态“执行规则”再次保留
  • 状态“流程成功结束”被保留

我最终得到了这六个州:

  • 咨询政府政策
  • 咨询政府政策
  • 执行规则
  • 咨询政府政策
  • 执行规则
  • 流程已成功结束

而不是预期的三个:

  • 咨询政府政策
  • 执行规则
  • 流程已成功结束

有谁知道为什么?有什么建议读什么来理解这里发生的事情?

1 个答案:

答案 0 :(得分:3)

你正在保存相同的AccountRequest request三次,只需使用request.addState(new State(stateDescription));将对象添加到列表中,所以hibernate会保存它,因为我应该说。

详细说明:

1st saveState() : 
        adding "Consulting government policies" 
        saving request with the list -> list.size()=1
2nd saveState() : 
        adding "Enforcing rules"
        saving request with the list -> list.size()=2
3d  saveState() : 
        adding "Process ended successfully"
        saving request with the list -> list.size()=3

另请注意,如果您尚未配置正确的Executor,或者您已将@Async置于同一类中调用的方法之上,则它将无法正确包装,因此它不会异步运行。
现在,如果您在没有@Async的情况下调用相同的方法时遇到不同的行为,那么您可能会遇到事务管理器或持久性单元的问题,因此它会立即刷新会话,从而导致3个连续的 new 插入数据库。如果会话没有立即刷新/提交事务,则会导致3次合并 - > 1个最终插入与完整列表。

某些网站链接仅供参考。

Spring Async Example
Hibernate Cascade
Entity Manager