如何解决JPA锁定PESSEMISTIC_WRITE和FEW事务
我在存储库方法上使用了PESSEMSTIC_WRITE锁。因此,这将锁定我的对象直到交易结束。但是,我遇到了一个问题,在一个端点内,控制器->服务->我开始交易,然后我需要更新我的对象并将消息发送到kafka,之后,我需要在此方法内再次更新我的对象并发送到kafka 。因此,因为这是一个事务,所以更改仅在缓存中本地生效。但是我需要保存在数据库中然后发送到kafka,然后再次更改我的对象并保存到数据库并发送到kafka消息,我不能使用REQUIRES_NEW并以任何方式创建新事务,因为我的对象已被锁定。那么我该如何处理呢? 此锁在我的项目的许多部分中用于修复并行事务。
解决方法
您应该创建新的服务以协调流程。这样,您将可以在第二个操作中再次获得相同的悲观锁。
@Service
class OrchestratorService {
...
void executeFlow() {
someService.executeFirstOperationAndSendKafkaEvent()
someService.executeSecondOperationAndSendKafkaEvent()
}
}
@Service
class SomeService {
@Transactional(REQUIRES_NEW)
void executeFirstOperationAndSendKafkaEvent() {
// any lock which obtained inside this method will be released once this method finishes
...
}
@Transactional(REQUIRES_NEW)
void executeSecondOperationAndSendKafkaEvent() {
// any lock which obtained inside this method will be released once this method finishes
...
}
}
还有一个值得一提的重要方面-发送kafka事件不是事务性的。 @Transactional
仅保证对数据源所做的更改将是事务性的(在本例中为DB)。因此,可能出现以下情况:
- 如果事件是在事务范围内发送的,则在成功发送kafka事件后可以回滚事务
- 如果事件是在事务提交之外发送的,则在成功提交事务后事件发送可能会失败
由于这种性质,将流程分为几个阶段是很好的:
- 在数据库中应用业务更改,并在数据库中存储一个应该发送kafka事件的标志,但尚未完成,
- 外部TX范围将事件发送到kafka
- 在新的TX中更改已发送事件的标志,或者在发送事件期间发生错误时安排重试。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。