我想锁定一个表,以便其他线程不能插入任何行(例如)user_id = 5.而其他线程正在处理这些行集。 虽然我可以锁定整个表,但这看起来太多,会降低并发性。
我的线程确实关注,并且有很多一次运行。
Start Transaction
1) insert row with user_id=val
2) if (count (*) >= 2) where user_id = val and some other conditions then do "something"
COMMIT
现在如果2个线程并行运行,那么它们都可能会得到count(*)= 1,但是当它们都提交时,总行数是2,那应该是那个""
我认为我需要在每个事务中使用user_id = val锁定行,这样在我的事务完成之前,任何人都无法插入user_id = val。
有没有办法使用MySQL和Hibernate实现这一目标。
答案 0 :(得分:1)
使用锁定读取。
SELECT COUNT(*)FROM table WHERE user_id = val FOR UPDATE。
将锁定匹配的行,直到事务结束。
http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html
答案 1 :(得分:0)
考虑使用GET_LOCK()
;
选择特定于要锁定的行的名称。例如'xxx_user_id_y'
。其中'xxx'
是特定于过程的字符串或在此表上插入,'y'
是用户ID。
调用SELECT GET_LOCK('xxx_user_id_y',30)
锁定名称'xxx_user_id_y'
..如果名称可用,它将返回1并设置锁定;如果30秒后锁定不可用,则返回0(第二个参数是超时)。
完成后使用SELECT RELEASE_LOCK('xxx_user_id_y')
。
注意;您必须在每个要等待的事务中使用相同的名称,并在事务中再次调用GET_LOCK()
将释放先前设置的锁。