我读过这个: Transaction safe insertion of node in nested set?
但我担心在嵌套集模型中锁定插入新节点。 我想在我的树类别中插入一个新节点,但我想确保插入新节点而不会损坏。 mysql中使用的引擎是InnoDb。 正如其他问题所说:
BEGIN; -- or whatever API your framework has for starting a transaction
SELECT @myLeft := lft FROM myTable WHERE ID = $id FOR UPDATE;
UPDATE myTable SET rgt = rgt + 2 WHERE rgt > @myLeft;
UPDATE myTable SET lft = lft + 2 WHERE lft > @myLeft;
INSERT INTO myTable(title, lft, rgt) VALUES($title, @myLeft + 1, @myLeft + 2);
COMMIT; -- or whatever API your framework has for commiting a transaction
我的问题是,如果并发用户尝试在同一个树中插入新节点,事务是否足以进行更新并调整其他节点的左右? 如果user1添加新节点(在transaction1中执行)并且同时user2添加新节点(在transaction2中执行),我确定user2在user2插入新节点之前读取user1添加节点的更新树? 那么,100个用户在同一时间插入新节点,只要预览用户完成总是有一致性树,最后用户必须等待?
答案 0 :(得分:0)
InnoDB进行行级锁定。因此,正在更新的行将在事务期间被锁定。这可能会导致阻塞和死锁。
如果正在更新行,InnoDB将无法获取该行的锁定以再次更新它。这有效地序列化了交易。请注意,可以控制事务隔离级别,请参阅此链接http://dev.mysql.com/doc/refman/5.1/en/dynindex-isolevel.html
这里还有一篇关于如何在innodb引擎http://www.xaprb.com/blog/2006/07/31/how-to-analyze-innodb-mysql-locks/中查找死锁的有趣文章。
如果嵌套集正在进行大量更新,请确保您具有正确的隔离级别,并且在事务中包装语句就足够了。但是,它可能会产生您需要编码的锁定,阻塞和死锁问题。