在使用 InnoDB 存储引擎的 Web 应用程序中,我无法在以下场景中充分利用数据库锁定。
有 3 张桌子,我会称它们aa
为ar
和ai
。
aa
保存基本记录,比方说文章。ar
保存与每条记录相关的信息以及和之间aa
的关系。aa
ar
1:m
第一次读取来自的记录ar
时,会存储记录。问题在于,当两个请求以(几乎)相同的方式启动以从中读取记录(其相关记录尚未存储在 中)时,记录会重复。aa
aa
ar
ar
下面是一个伪代码来帮助理解这种情况:
读取请求的
aa
记录。扫描
ar
表以查明给定aa
记录是否已存储任何内容。(假设它没有。)咨询
ai
以找出ar
给定aa
记录要存储的内容。(ai
似乎有些无关紧要,但我发现它也必须参与锁定......可能是错误的。)插入几行到
ar
这是我想要实现的目标:
- 读取请求的
aa
记录。
无论是否使用事务,锁定ar
,因此任何后续尝试读取的请求都将在此时ar
等待,直到完成。
扫描
ar
表以查明给定aa
记录是否已存储任何内容。(假设它没有。)问题是在两个同时请求的情况下,两者都发现给定记录中没有记录,并且它们都继续插入相同的行两次。ar
aa
否则,如果有,则中断此序列并且不发生 INSERT。咨询
ai
以找出ar
给定aa
记录要存储的内容。(ai
似乎有些无关紧要,但我发现它也必须参与锁定......可能是错误的。)插入几行到
ar
解除锁定ar
看起来很简单,我没有成功避免重复。我正在测试来自 Bash shell 中一个简单命令的同时请求(使用 wget)。
我花了一段时间在http://dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.html和这里http://dev.mysql 了解 InnoDB 引擎的锁定是如何工作的。 com/doc/refman/5.5/en/innodb-locking-reads.html并尝试了几种利用锁的方法,仍然没有运气。
我希望锁定整个ar
表(因为我想防止 INSERT 发生多个请求)导致进一步尝试与该表交互以等待第一个锁被释放。但是文档中只提到了“整个表”被锁定(第一个链接页面中的意向锁部分),但没有进一步讨论,或者我无法弄清楚如何实现它。
谁能指出正确的方向?