【问题标题】:ChainedTransaction Manager throws HeuristicCompletionException and not RollbackChainedTransaction 管理器抛出 HeuristicCompletionException 而不是 Rollback
【发布时间】:2020-11-26 18:55:49
【问题描述】:

我有 chainedTransactionManager 和两个不同的数据源。我的问题是 MydataSource1 实体在数据库中有一个唯一的约束违规。Mydatasource1.save 工作然后它传递给 mydatasource2.save 然后它抛出 HeuristicCompletionException 和 mydatasource2.save 工作而不是回滚。什么如果发生任何异常,我希望无条件回滚

> org.springframework.transaction.HeuristicCompletionException:
> Heuristic completion: outcome state is mixed; nested exception is
> org.springframework.dao.DataIntegrityViolationException: could not
> execute statement; SQL [n/a]; constraint [MYSchema.UNIQUE_NAME]; nested
> exception is org.hibernate.exception.ConstraintViolationException:
> could not execute statement\r\n\tat
> org.springframework.data.transaction.ChainedTransactionManager.commit(ChainedTransactionManager.java:177)\r\n\tat
> org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:619)\r\n\tat
> org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:372)\r\n\tat

@Transactional(rollbackFor = {Exception.class,Throwable.class}, isolation = Isolation.READ_COMMITTED, transactionManager = "MychainedTransactionManager", propagation = Propagation.REQUIRED)
        public void saveMultipleDBSource() 
    {
    ...........
    MyDataSource1.Save(Entity1)
    
    MyDataSource2.Save(Entity2)
    
    }

【问题讨论】:

  • 您为什么不使用saveAndFlush() 而不是save(),这样在您到达MyDataSource2.Save(Entity2) 之前,任何违反约束的行为都会提前发现
  • 我已经尝试了 saveandflush 但还是一样,因为在我的场景中,约束是在 dblevel 而不是 applicationlevel

标签: spring-boot spring-data-jpa spring-transactions distributed-transactions


【解决方案1】:

解决方法_1:

这里是tried and tested similar scenario,似乎已经被分析、讨论和解决了 我建议您尝试一下并浏览整个线程,这与您的情况类似。 目前,你得到一个状态:STATE_MIXED,而他得到一个状态:STATE_ROLLED_BACK

解决方法_2:

您还可以围绕目标区域进行异常处理,因为您遇到的异常是未经检查的异常。 由于您的要求很明确,如果您只想优雅地回滚,那么您可以尝试使用此spring documentation link 对此场景进行异常处理。

我希望,这对您有所帮助。谢谢你。 :)

【讨论】:

  • 感谢您的回答,但 PROPAGATION.REQUIRES_NEW 对我没有帮助,仍然是同样的错误
  • 好的,您可以尝试使用提供的 spring 文档围绕您的目标代码块进行异常处理(Workaround_2)。链接,因为您只想回滚。
  • 我不明白我已经放回滚异常,我在我的代码中添加了 try catch 但它没有命中
  • 首先,你不需要显式指定rollbackFor = {Exception.class, Throwable.class},因为spring默认会在发生错误时回滚事务。请参阅第 12.5.3 节回滚声明性事务docs.spring.io/spring/docs/3.2.6.RELEASE/… 从@Transactional 中删除“rollbackFor”属性,然后在您的保存( ) 方法。
  • 我删除了回滚,没有任何改变。在我的情况下,尝试 catch 无法帮助,因为在 @transactional 内部逻辑出错之后我无法捕捉它们
猜你喜欢
  • 2018-03-17
  • 1970-01-01
  • 2017-05-15
  • 2021-05-09
  • 2015-12-14
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多