Spring 事务 - 在特定方法下不回滚错误

Spring Transaction - Do not rollback for error under specific method

我有一个 Spring 引导应用程序,其中的服务负责创建业务实体。为简单起见,让我们考虑:

create(Object toCreate) {
  validationService.validate(toCreate);
  Object created = repository.save(toCreate);
  notificationService.notify(created);
}

业务发生了变化,现在我希望创建如果通知失败不会失败。

因此,我将 notify() 方法包装在一个 try-catch 块中,该块只记录错误(这是一个 RuntimeException)。

但是在测试时,抛出事务回滚错误,说连接已关闭。我不想要任何回滚,特别是因为 NotificationService 不修改数据库。

如何告诉 Spring NotificationService 中发生的任何异常都很好并且不需要回滚?我尝试用 @Transactional(propagation=NEVER) 注释 class/method 但得到 existing transaction found for transaction marked with propagation 'never'

您可以使用@Transactional 的 norollbackfor 选项,因此您必须指定异常 class 而不是服务,并且当通知中发生错误时尝试抛出不会导致回滚的特定错误。

也许重构您的代码比引入更复杂的事务处理更有帮助。

假设您的 @Transactionalcreate() 方法上,我们可以看到您有:

  1. 预持久化业务逻辑
  2. 持久化逻辑
  3. Post-持久化业务逻辑

这取决于您的用例,但我不希望有积分。 1 & 3 包含持久性逻辑。如果是这种情况,您可以在它自己的服务中提取持久性逻辑,该服务本身就是一个事务,而不是父事务。

如果你在那些步骤中有事务的需求,你也可以在自己的事务中提取它们。

其他线索可能是:

  1. default rollback behavior is for runtime unchecked exceptions。您可以使用已检查的异常来避免回滚。
  2. 如果您的通知与持久性分开并且您不关心事务,您可以将其设为异步调用(例如 @Async)。它将在其自己的上下文中安排在事务之外。