是否可以锁定表以插入所选值

时间:2014-08-20 10:31:16

标签: mysql

我想锁定一个表,以便其他线程不能插入任何行(例如)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实现这一目标。

2 个答案:

答案 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()将释放先前设置的锁。

GET_LOCK() docs