首页 > 解决方案 > 如何使用 Hibernate 控制 INSERT 语句中的并发性

问题描述

通过我的 Web 应用程序插入数据时,我无法控制并发性。

上下文:我有 3 张表(X、Y 和 Z)记录患者的住院情况。一名患者不能接受超过一次的住院治疗。

目前,我的应用程序在数据库中的住院 INSERT 之前进行验证,检查患者是否已经住院。

但是,当两个或更多用户尝试同时接纳同一患者时,此验证不起作用。

我现在应该做什么:

1 - verify if patient is already hospitalized (SELECT in table X)
  If not:
    begin transaction A;
      2 - INSERT in table X;
      3 - INSERT in table Y;
      4 - INSERT in table Z;
    end transaction A;

正如我之前提到的,1中的验证试图避免患者住院两次或更多。但是,如果两个(或更多)用户尝试同时收治同一患者,则它不起作用。

也许我可以使用一些东西来锁定 SELECT 语句的执行,直到事务 A 完成。这样,SELECT 将在执行时识别出患者已经注册。

我想在数据库中使用来自 PostgreSQL 的EXPLICITING LOCKING来处理这个问题。根据文档,我可以使用 ACCESS EXCLUSIVE 锁定模式执行类似的操作(因为它是唯一能够锁定 select 语句的模式)。

但是如何在 Hibernate 中实现这个 ACCESS EXCLUSIVE 锁呢?

我已经检查过并且无法使用数据库中的约束来处理这个问题

标签: javadatabasehibernateweb-applicationsconcurrency

解决方案


为了确保单个患者不会有两次住院治疗,您需要向字段添加唯一约束,该字段是从 X(和/或 Y,Z)到患者的引用(我假设已经有一个字段,如patient_idat至少在这些表之一中,否则您如何引用插入到 X、Y 和 Z 中的记录的患者)。

在这种情况下,数据库将保证您不能将给定患者的多个记录插入表中。

如果住院已经存在,您需要捕获唯一约束违反异常并执行您想做的任何事情。


推荐阅读