Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jakarta ee JPA 2.0-等待线程释放的db锁在释放后是否确实获得了数据?或者只是以防万一它仍然符合最初的标准?_Jakarta Ee_Jpa_Db2_Jpa 2.0_Openjpa - Fatal编程技术网

Jakarta ee JPA 2.0-等待线程释放的db锁在释放后是否确实获得了数据?或者只是以防万一它仍然符合最初的标准?

Jakarta ee JPA 2.0-等待线程释放的db锁在释放后是否确实获得了数据?或者只是以防万一它仍然符合最初的标准?,jakarta-ee,jpa,db2,jpa-2.0,openjpa,Jakarta Ee,Jpa,Db2,Jpa 2.0,Openjpa,我有一个多线程环境(集群的,甚至多JVM),其中有很多线程同时查询单个db表。所有这些线程都在执行完全相同的查询,查找状态为“可用”的任意实体。如果一个线程发现一个“可用”实体,它会将其状态更改为“阻塞”,并将其分派给业务逻辑,由业务逻辑执行后续工作。对“可用”实体的查询是一个悲观写锁查询,因此,对于试图同时访问同一行的任何其他线程,db表中的对应行都会被锁定。所有其他线程都必须等待,直到前面的线程释放数据库中的锁 现在我的问题是:在任何情况下,等待释放某个实体上的锁的线程在释放锁后是否会收到该

我有一个多线程环境(集群的,甚至多JVM),其中有很多线程同时查询单个db表。所有这些线程都在执行完全相同的查询,查找状态为“可用”的任意实体。如果一个线程发现一个“可用”实体,它会将其状态更改为“阻塞”,并将其分派给业务逻辑,由业务逻辑执行后续工作。对“可用”实体的查询是一个悲观写锁查询,因此,对于试图同时访问同一行的任何其他线程,db表中的对应行都会被锁定。所有其他线程都必须等待,直到前面的线程释放数据库中的锁


现在我的问题是:在任何情况下,等待释放某个实体上的锁的线程在释放锁后是否会收到该特定实体?即使实体的状态不再满足初始查询条件?在我上面的场景中,如果第二个线程查询状态为“可用”的某个实体,并找到当前被第一个线程(写)锁定的实体,这是否意味着第二个线程在任何情况下都会在其释放后获得该实体,即使第一个线程在释放锁之前将其状态更改为“Blocked”?

问题是特定于数据库的,与JPA无关。答案是:只有当Thread2仍然满足您的搜索条件时(否则:那是什么类型的数据库?:您请求苹果,它返回桔子),Thread2才会收到该特定实体(其锁首先由Thread1持有)

现在,如果您想自己测试它,请打开两个控制台会话到您的数据库,然后自己尝试


PS:还考虑等待锁释放的超时时间。

< P>悲观锁定:

在您的场景中,查询1获取状态为“可用”的行,然后将状态更新为“已阻止”。如果未提交(或回滚)此更新,则当搜索“可用”行的其他查询尝试读取此行时,它们将等待–锁定时无法读取该行的值

如果查询1提交了更新(即状态现在为“已阻止”),则其他查询将无法获得该行

如果查询1执行回滚(行的状态恢复为“可用”),则其他查询将在其结果集中获取该行

为了在这种情况下实现最佳并发性,请确保事务尽可能短地执行此更新(即,将执行后续工作的业务逻辑分离到单独的事务中)。当业务逻辑完成时,对其成功/失败做出决定,然后再次更新相关行的状态

“这是否意味着第二个线程将在其 在任何情况下都可以释放,即使第一个线程更改其状态(…) 就在释放锁之前?”

我认为这在很大程度上取决于持久性提供者和底层数据库 JPA规范说明了要实现什么而不是如何实现

如JPA 2.0规范第3.4.3章悲观锁定所述:

本规范未定义持久化的机制 提供程序用于获取数据库锁和可移植应用程序 不应依赖于在上实现悲观锁定的方式 数据库
。例如,持久性提供程序可以使用底层 数据库平台的
选择更新
语句以实现 悲观锁定如果该构造提供了适当的语义, 或者,提供程序可以使用可重复读取的隔离级别


另一方面,如果底层数据库并发控制机制提供可比较的语义(即两阶段锁定或多版本并发控制),则使用
LockModeType.悲观写入
可确保可重复读取,从而防止不可重复读取和脏读异常这在您的特定情况下就足够了,因为OpenJPA提供了悲观的写锁定,DB2提供了满足条件的RS或RR隔离级别