2010-12-15 65 views
0

我正在使用SELECT...FOR UPDATE查询来锁定表。不幸的是,我有一个情况我需要锁定两个不同的行集在同一个表,像这样:锁定同一个表两次

SELECT * FROM mytable WHERE attribute1 = 'something' FOR UPDATE 
SELECT * FROM mytable WHERE attribute2 = 'somethingelse' FOR UPDATE 
UPDATE mytable SET attribute2 = 'somethingnew' WHERE somethingelse 

我需要锁定的两套行。我所做的是确保表格中的所有对象都不处于特定状态,然后查找可以放入该状态并将其放置在其中的其他对象。目标是满足某些过于复杂的约束,无法编码到MySQL中。

所以......问题是,当我在同一个事务中的相同表中两次出现两次时会发生什么?第一把锁是否被释放?我已经看到证据证明情况是这样,但我无法弄清楚如何确认。

+0

您是否在发出SELECT之前将autocommit设置为0或启动事务? – outis 2010-12-15 15:58:13

回答

0

如何像

SELECT * FROM mytable WHERE attribute1 = 'something' 
    or attribute2 = 'somethingelse' FOR UPDATE 

UPDATE mytable SET attribute2 = 'somethingnew' WHERE somethingelse 

我不知道直接的回答你的问题,但MySQL手册说,锁定了一个发布在交易完成后(COMMITED或回滚),这意味着第二选择不释放锁。在你的情况下,你实际上并不需要两个选择。

0

锁只在提交或回滚时释放。另一方面,单个事务本身不会阻塞。所以上面应该没问题,只要只有一个线程正在做。

如果多于一个线程正在运行上面,我担心你会死锁。如果你想这样做,你需要一个同时锁定两个集合的SQL语句,例如Jaydee的回答如上。