Propagation.REQUIRES_NEW会给我的应用带来什么附带效果

时间:2017-06-21 11:57:40

标签: java spring hibernate spring-mvc hibernate-session

我收到了这样的错误

  

具有相同标识符值的其他对象已与会话关联:

我已经搜索过并发现可以使用CascadeType.MERGE修复它,或者重构大量代码以防止同一个数据库对象成为会话中的两个实例。

我无法重构它。

CascadeType.MERGE有效,但这意味着我必须编写很多代码才能解决删除问题,因为它之前是.ALL,对吗?

我让它正常工作推出

@Transactional(propagation = Propagation.REQUIRES_NEW)

在一个带有@Service注释的类的方法之上,该查询数据库是抛出我提到的异常的那个。

我需要帮助才能理解这个新的带注释的方法是否会给我带来任何未来的痛苦。

除了我正在修复的行动之外,正在从一些cron工作中调用它。

2 个答案:

答案 0 :(得分:2)

实际上,您通过使用@Transactional(propagation = Propagation.REQUIRES_NEW)

注释方法为方法调用创建单独的事务

这意味着如果从方法中抛出异常,则会应用所有数据库更改(保存等)并且不会回滚。这可能会严重损害业务逻辑,并可能成为数据库中不一致数据的来源。

我会重新考虑应用Propagation.REQUIRES_NEW

在这种情况下,合并听起来更合适。

答案 1 :(得分:1)

您列出的解决方案都不可接受恕我直言。

将某个部分处理推迟到新事务将破坏您的工作单元的原子性(全部或全部),并且更改级联类型将意味着您手动处理之前自动级联的所有操作。

正确的方法是理解为什么hibernate遇到具有相同标识符的2个不同对象实例,最常见的原因是因为您手动持久(保存)具有固定标识符的分离/瞬态对象,而此对象已存在于会话中(具有相同标识符的托管对象已在会话中)。

您可以尝试手动重新附加(合并/更新/ saveOrUpdate)导致问题的分离对象实例。

您必须了解entity lifecycle才能正确理解此处发生的事情。