【发布时间】:2015-06-22 14:41:17
【问题描述】:
我正在使用 MySQL 和在 CentOS 6.6 x64 和 PHP 5.5 上运行的 InnoDB 插件版本 5.5。隔离级别设置为 REPEATABLE-READ。
我将大约 40,000 条记录摄取到一张表中。如果我只导入大约 500 条记录,则一切正常。
其中一些记录可能具有重叠的日期时间范围。如果他们这样做了,那么在 PHP 中会执行几个步骤。
要检查重叠记录,执行 SELECT,如果返回空,我可以插入新记录。如果有记录返回,则执行以下步骤。
- 使两条重叠记录(记录 A)中较旧的记录无效
- 将旧记录的非重叠部分复制到新记录(记录 C)中并插入该记录
- 插入两条重叠记录中较新的一条(记录 B)
当我为 40,000 个记录案例运行摄取时,我可以看到重叠的日期范围,这意味着选择查询没有返回任何内容,然后导致特殊的重叠处理没有触发。同样,在较小的摄取案例中,所有这些逻辑都可以正常工作,并且我在这两种情况下都查看了相同的特定重叠日期范围。
此时,在我看来,当下一次选择重叠检查发生时,在逻辑的下一个循环中没有看到插入提交。
我开始研究表锁定、事务和隔离级别的选项,但不确定最好的方法是什么。
【问题讨论】:
-
您必须展示您的实际查询/php 逻辑。如果您使用可重复读取,则事务中执行读取的所有内容都应获得相同的值。
-
各种查询故意不在事务内部,因为它们需要使用最新的实际数据。我不希望重新读取相同的数据
-
如果没有交易在起作用,那么 read-repeatable 并没有真正进入图片...
-
了解并感谢您的澄清。我试图弄清楚为什么循环中的第 n 次迭代正在插入数据而第 n+1 次循环没有看到该数据。查看 Locking 和 Innodb ACID 配置让我看到了隔离(错误地)。
-
MySQL PDO 驱动程序就是这样的错误(我见过更奇怪的事情发生)。如果可以,我建议您使用存储过程。或者尝试在每次迭代时手动启动和结束事务,而不是依赖自动提交(不要忘记停用模拟准备)。或者尝试通过在查询之间引入一点延迟来调整插入速度。