java—有没有一种基于sql查询锁定块执行的方法?

noj0wjuj  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(298)

背景:我有一个迷你聊天应用程序,可以让你为许多对话者创建聊天室。一组特定对话者的聊天室只能创建一次,因此,如果创建同一组对话者聊天室的请求将执行两次,则只能创建一个聊天室:
因此:
对话者1和对话者2的http post/聊天室->创建聊天室
对话者1和对话者2的http post/聊天室->跳过创建聊天室,因为已经存在
基本上,这是一个简单的多对多关系,有三个表:聊天室、聊天室、对话者和对话者
当使用单线程环境时,一切似乎都正常,但是,在多线程上,我最终为同一组对话者创建了重复的聊天室。这似乎是一个经典的并发问题,可以通过锁定机制解决,但是当两个或多个微服务示例可用时,应该将锁定委托给数据库级别。
因为我使用的是spring boot,所以我试过使用它 @Lock(LockModeType.PESSIMISTIC_READ) 然而,在jpa查询中,第二个线程没有挂起查询,而是创建了重复的聊天室。查询如下所示:

select c.chat_id from chat c
join chat_interlocutor c1 on  c1.chat_id = c.chat_id and c1.interlocutor_id = ?1
join chat_interlocutor c2 on c2.chat_id = c.chat_id and c2.interlocutor_id = ?2

整个场景如下所示:
微服务1
检查两个对话者之间是否存在聊天(对话者1和对话者2)
它不存在,所以创建它
微服务2
检查两个对话者(对话者1和对话者2)之间是否存在聊天,[此处MicroService 1尚未提交]
它不存在,所以创建它[这里我们创建的是重复的聊天室]

7xzttuei

7xzttuei1#

最简单的解决方案是在数据库中使用一个独特的聊天室id作为同步机制(在微服务之间共享)。
要使其工作,您必须在会话启动时创建聊天室实体。您必须确保它始终使用由2名参与者确定的唯一id创建。如果创建成功,则这是一个新的聊天室,如果存在唯一密钥冲突,则聊天室已经存在。
您描述的流程几乎是正确的,但是您错过了在数据库中创建聊天室的过程,该聊天室具有由microservice构建的唯一id。您仍然需要检查聊天室是否已经存在,因为这样可以避免太多的冲突。

相关问题