gpt4 book ai didi

mysql - 如何使用 doctrine2 锁定 symfony2 中的整个表?

转载 作者:可可西里 更新时间:2023-11-01 06:47:05 25 4
gpt4 key购买 nike

我需要用 doctrine 锁定整个表(而不是单个行),如果可能的话,我想在没有 native 查询的情况下执行此操作。

pessimistic locking 的文档仅描述如何通过这些方法锁定特定实体:

  • EntityManager#find
  • EntityManager#锁
  • 查询#setLockMode

我有一个事务需要插入一行,该行的值取决于表中其余行的值,因此我需要防止两个事务同时在该表上执行。

我正在使用显式事务划分,它应该可以很好地与锁定一起工作(根据上面的文档)。

注意:乐观锁在这种情况下不够好,我不能重试事务。此外,查询不应该很慢,因此性能不是问题。

编辑:我举个例子。想象一下,您想要手动构建一个 auto_increment,并且您必须从表中选择 max() 以获得前一个结果,以便插入下一个。您必须确保没有两个事务尝试插入相同的值,以防它们同时选择 max()。

当 auto_increment 不好时,我正在寻找解决此问题的通用解决方案,例如使用字符串、多列、散列或您必须对前一个行集进行的任何计算。

锁定是一个可靠的解决方案,与乐观锁定不同,您不必重试错误。

那么,在doctrine中有没有什么方法可以使用table locking呢?

最佳答案

按照目前的建议,我尝试了这个:

$em->getConnection()->exec('LOCK TABLES table_name WRITE;'); //lock for write access

// calculate $new_number...

// persist $new_number on table_name...
$table_name->setCalculatedNumber($new_number);
$em->persist($table_name);
$em->flush();

$em->getConnection()->exec('UNLOCK TABLES;');

我用 JMeter 对其进行了测试,锁定在高负载(16 个请求/秒)下无法正常工作。跟踪显示其他实例在明确放弃之前获得了锁。问题(正如 Jens 所建议的那样)是 flush() 隐式地以 START TRANSACTION 开始,这会删除表锁。使用 native 更新为我解决了问题:

$em->getConnection()->exec('LOCK TABLES table_name WRITE;'); //lock for write access

// calculate $new_number...

// persist $new_number on table_name...
$em->getConnection()->executeUpdate("UPDATE table_name set ...;");

$em->getConnection()->exec('UNLOCK TABLES;');
$em->refresh($table_name);

需要尾随的 refresh() 才能使计算出的数字在后续查询结果中可用

关于mysql - 如何使用 doctrine2 锁定 symfony2 中的整个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11256169/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com