java 使用 JPA 的表排他锁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32336481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:02:38  来源:igfitidea点击:

Table exclusive lock with JPA

javajpalocking

提问by Radek Posto?owicz

Is it possible to lock exclusively entire table with JPA in database agnostic way (without using native queries for instance)? So far I saw only EntityManager.lock(*)but this locks only given record.

是否可以以数据库不可知的方式使用 JPA 锁定整个表(例如,不使用本机查询)?到目前为止,我只看到了EntityManager.lock(*)这个锁只给出了记录。

回答by OndroMih

I don't think this is supported by JPA natively - you always lock single entity or every entity which is a result from a query. Inserts are always allowed as they are new entities. You may either use native query to trigger a lock using SQL supported by your DB server, or you need to lock your insert programmatically.

我认为 JPA 本身不支持这 - 您总是锁定单个实体或每个查询结果的实体。始终允许插入,因为它们是新实体。您可以使用数据库服务器支持的 SQL 使用本机查询来触发锁定,或者您需要以编程方式锁定您的插入。

By programmatically I mean that you need to acquire a lock before every insert. You may do it by creating a separate lock entity class, each entity for a table you want to lock, and then before each insert, you lock particular entity with a read lock like this:

以编程方式我的意思是你需要在每次插入之前获取一个锁。您可以通过创建一个单独的锁定实体类来实现,每个实体都用于要锁定的表,然后在每次插入之前,使用读取锁锁定特定实体,如下所示:

em.createQuery("select l from TableLock l where l.entity = :entityName", TableLock.class)
   .setParameter("entityName", MyEntity.class.getSimpleName())
   .setLockMode(LockModeType.PESSIMISTIC_READ)
   .getResultList();
em.persist(new MyEntity());

Of course, you should also check if the lock entity exists in database, and if not, create it first, with entity field being the name of your entity.

当然,您还应该检查数据库中是否存在锁定实体,如果不存在,请先创建它,实体字段为您的实体名称。