【问题标题】:nested set model (hierarchical data) mysql - concurrent users insert new node in consistency way嵌套集模型(分层数据)mysql - 并发用户以一致性方式插入新节点
【发布时间】:2012-05-07 12:55:24
【问题描述】:

我读过这个: 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 个用户在同一时间插入新节点,最后一个用户必须等待用户完成预览才能始终拥有一致性树?

【问题讨论】:

    标签: mysql concurrency tree nested


    【解决方案1】:

    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/ 中查找死锁的有趣文章。

    如果嵌套集被大量更新,请确保您具有正确的隔离级别并将语句包装在事务中就足够了。但是,它可能会产生您需要编写代码来解决的锁定、阻塞和死锁问题。

    【讨论】:

    • 我对锁定、阻塞和死锁感到沮丧,因为我不能接受用户等待很长时间或锁定模拟故障服务。如果我不锁定并且只使用事务,树可能会损坏,如果我使用事务并且我使用锁可能会阻塞所有。不同的方式或解决方案?较小的邪恶?
    • 确实如此。但是,我认为宁愿让用户等待一段时间,也不要让他们不信任的损坏的数据库。有一些方法可以让 innodb 运行得更快。例如将 innodb 安装在单独的 RAID 阵列上。这将允许 innodb 表具有专用的 IO。您需要对其进行压力测试,然后设定用户的期望。如果您告诉用户当 1000 万人同时插入记录时速度会变慢,您的抱怨可能会减少。
    • 使用 SELECT...LOCK IN SHARE MODE 会更合适吗?根据文档“SELECT ... LOCK IN SHARE MODE 对读取的任何行设置共享模式锁。其他会话可以读取这些行,但在您的事务提交之前不能修改它们。如果这些行中的任何一个被另一个事务更改尚未提交,您的查询将等到该事务结束,然后使用最新值。”如果 user1 添加节点,我可以锁定正在添加节点的树行,其他用户已经可以读取数据,但同时其他用户无法修改数据,直到 user1 进程中的事务正在运行
    • 这肯定有助于提高阅读速度。您将需要尝试不同的设置以获得最佳性能。不幸的是,没有适用于所有条件的正确答案。你必须为你的条件找到最成功的方法。嵌套集可以快速检索记录,您只需要加快写入速度即可。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多