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 而不是服务,并且当通知中发生错误时尝试抛出不会导致回滚的特定错误。
也许重构您的代码比引入更复杂的事务处理更有帮助。
假设您的 @Transactional
在 create()
方法上,我们可以看到您有:
- 预持久化业务逻辑
- 持久化逻辑
- Post-持久化业务逻辑
这取决于您的用例,但我不希望有积分。 1 & 3 包含持久性逻辑。如果是这种情况,您可以在它自己的服务中提取持久性逻辑,该服务本身就是一个事务,而不是父事务。
如果你在那些步骤中有事务的需求,你也可以在自己的事务中提取它们。
其他线索可能是:
- default rollback behavior is for runtime unchecked exceptions。您可以使用已检查的异常来避免回滚。
- 如果您的通知与持久性分开并且您不关心事务,您可以将其设为异步调用(例如
@Async
)。它将在其自己的上下文中安排在事务之外。
我有一个 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 而不是服务,并且当通知中发生错误时尝试抛出不会导致回滚的特定错误。
也许重构您的代码比引入更复杂的事务处理更有帮助。
假设您的 @Transactional
在 create()
方法上,我们可以看到您有:
- 预持久化业务逻辑
- 持久化逻辑
- Post-持久化业务逻辑
这取决于您的用例,但我不希望有积分。 1 & 3 包含持久性逻辑。如果是这种情况,您可以在它自己的服务中提取持久性逻辑,该服务本身就是一个事务,而不是父事务。
如果你在那些步骤中有事务的需求,你也可以在自己的事务中提取它们。
其他线索可能是:
- default rollback behavior is for runtime unchecked exceptions。您可以使用已检查的异常来避免回滚。
- 如果您的通知与持久性分开并且您不关心事务,您可以将其设为异步调用(例如
@Async
)。它将在其自己的上下文中安排在事务之外。