Jen*_*ens 6 mysql locking symfony doctrine-orm
我需要使用doctrine来锁定整个表(不是单行),如果可能的话,我希望在没有本机查询的情况下执行此操作.
悲观锁定的文档仅描述了如何通过以下方法锁定特定实体:
我有一个需要插入行,其值取决于表中的行的其余部分的值的交易,所以我需要防止两个事务执行,同时该表.
我正在使用显式事务划分,这应该适用于锁定(根据上面的文档).
注意:在这种情况下乐观锁定不够好,我负担不起重试事务.此外,查询不应该很慢,因此性能不是问题.
编辑:我举个例子.想象一下,你想手工构建一个auto_increment,你必须从表中选择max()来获取前一个结果才能插入下一个结果.您必须确保没有两个事务尝试插入相同的值,以防它们同时选择max().
当auto_increment不好时,我正在寻找这个问题的一般解决方案,例如使用字符串,或多列,哈希或您必须在前一行集上进行的任何计算.
锁定是一个可靠的解决方案,与乐观锁定不同,您不必重试错误.
那么,有没有办法在学说中使用表锁定?
到目前为止,按照建议,我尝试了以下方法:
$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;');
Run Code Online (Sandbox Code Playgroud)
我用 JMeter 对其进行了测试,锁定在重负载(16 个请求/秒)下不起作用。跟踪显示其他实例在明确放弃锁之前就获得了锁。问题(正如 Jens 所建议的)是,flush() 隐式地以 START TRANSACTION 开始,这会删除表锁。使用本机更新解决了我的问题:
$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);
Run Code Online (Sandbox Code Playgroud)
需要尾随的刷新()以使计算出的数字在后续查询结果中可用
| 归档时间: |
|
| 查看次数: |
9358 次 |
| 最近记录: |