微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JPA锁定PESSEMISTIC_WRITE和FEW事务

如何解决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事件后可以回滚事务
  • 如果事件是在事务提交之外发送的,则在成功提交事务后事件发送可能会失败

由于这种性质,将流程分为几个阶段是很好的:

  1. 在数据库中应用业务更改,并在数据库中存储一个应该发送kafka事件的标志,但尚未完成,
  2. 外部TX范围将事件发送到kafka
  3. 在新的TX中更改已发送事件的标志,或者在发送事件期间发生错误时安排重试。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。