Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.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
Java 悲观锁定奇怪行为_Java_Multithreading_Hibernate_Grails_Gorm - Fatal编程技术网

Java 悲观锁定奇怪行为

Java 悲观锁定奇怪行为,java,multithreading,hibernate,grails,gorm,Java,Multithreading,Hibernate,Grails,Gorm,我正在开发一个模块,在这个模块中,我使用悲观锁定来锁定一行 我在服务方法中使用了以下代码: examSession = ExamSession.lock(ID) println "after lock " + new Date() ...... ........... examSession.addTo.........(object) .................................... examSession.save()........ ................

我正在开发一个模块,在这个模块中,我使用悲观锁定来锁定一行

我在服务方法中使用了以下代码:

examSession = ExamSession.lock(ID)
println "after lock " + new Date()
......
...........
examSession.addTo.........(object)
....................................
examSession.save()........
.......................................
trigger payment.......
...........................
当我在两个浏览器(几乎同时)中点击一个按钮以访问服务方法代码时,我发现另一个线程(第二个浏览器)在lock语句之后暂停,甚至不执行它后面的print语句。它在等待第一个线程完成/提交事务的3-4秒后执行。但是我已经读到,在悲观锁定的情况下,只有db read操作暂停。它应该至少执行了print语句。这是怎么发生的

Grails文档也没有详细指定lock()。请澄清。

ExamSession.lock(ID)
获取(或尝试获取)锁。显然,如果它已经被获取,执行将不会继续

这正是悲观锁定应该做的事情,它的工作原理与它应该做的完全一样。它不会在锁定语句之后暂停。它在
lock()
处暂停,因为它无法获取独占锁。

ExamSession.lock(ID)
获取(或尝试获取)锁。显然,如果它已经被获取,执行将不会继续


这正是悲观锁定应该做的事情,它的工作原理与它应该做的完全一样。它不会在
锁定语句之后暂停。它在
lock()
处暂停,因为它无法获取独占锁。

什么是
ExamSession.lock(ID)
?ExamSession是一个域类(相当于hibernate实体类)。lock()获取具有指定ID的行上的锁。什么是
ExamSession.lock(ID)
?ExamSession是一个域类(相当于hibernate实体类)。lock()获取具有指定ID的行上的锁。啊,,,你说得对+谢谢你的回复。我将其应用于并发座位预订,其中检查座位可用性,将座位分配给用户(先到先得),并触发付款。假设只剩下一个座位,那么只有一个用户可以申请该座位。你认为这是正确的方法吗?悲观锁定肯定会阻止多个用户尝试使用特定对象。但是,您很可能需要检查对象在
锁定()后是否仍然空闲,否则等待锁定的另一个用户将“超额预订”第一个用户所做的操作。您不希望这样。@Kayaman@viveksad实际上您希望读取
ExamSession
,并在读取时应用锁,以避免Kayaman描述的上述问题。在JPA中,这相当于使用
entityManager.find(ExamSession.class,theId,LockModeType.悲观_WRITE)。这意味着您要告诉数据库您要更新行,您要锁定它,读取它,然后将行返回给应用程序。在您提交或回滚事务之前,任何人都不能做任何事情,甚至不能阅读。@Naros感谢您提供的信息。卡亚曼。是的,在lock语句之后,我确实应用了验证,并检查了seatslaining是否大于0,然后只有book else返回并显示消息。啊,,,你是对的+谢谢你的回复。我将其应用于并发座位预订,其中检查座位可用性,将座位分配给用户(先到先得),并触发付款。假设只剩下一个座位,那么只有一个用户可以申请该座位。你认为这是正确的方法吗?悲观锁定肯定会阻止多个用户尝试使用特定对象。但是,您很可能需要检查对象在
锁定()后是否仍然空闲,否则等待锁定的另一个用户将“超额预订”第一个用户所做的操作。您不希望这样。@Kayaman@viveksad实际上您希望读取
ExamSession
,并在读取时应用锁,以避免Kayaman描述的上述问题。在JPA中,这相当于使用
entityManager.find(ExamSession.class,theId,LockModeType.悲观_WRITE)。这意味着您要告诉数据库您要更新行,您要锁定它,读取它,然后将行返回给应用程序。在您提交或回滚事务之前,任何人都不能做任何事情,甚至不能阅读。@Naros感谢您提供的信息。卡亚曼。是的,在lock语句之后,我确实应用了验证,并检查了seatslaining是否大于0,然后只有book else返回并显示消息。