我有一个查询,例如
Select count(*) from table log where num = ?;
如果我将隔离级别设置为可序列化,则将为where子句获取范围锁定。
我的问题是:其他交易是否也可以获得范围锁定在共享模式以读取上面的计数或范围锁定是独占的以及所有其他交易在执行上述读取查询之前等待当前事务提交。
背景 :我正在尝试为繁忙的网站实施一个视图计数器。为了减少数据库的IO,我创建了一个日志表,这样每次有一个视图时,我只在日志表中写一个新行。有一段时间,我(随机)决定是否要清除日志表并将日志表中的行数添加到视图计数表的列中。这意味着我必须小心交错事务。
答案 0 :(得分:0)
以下陈述仅与SQL Server相关,并且在OP明确表示这是关于MySQL之前做出的,我对此一无所知。我将它留在这里,因为它(以及由此产生的讨论)可能会有一些用处,但它不是一个完整的,相关的答案。
SELECT
语句只在所有隔离级别上获取共享锁(除非用表提示覆盖)。并且共享锁始终彼此兼容(请参阅Lock Compatibility),因此如果其他事务也想要获取共享(范围)锁,则没有问题。所以,是的,您可以同时执行SELECT COUNT(*)
任意数量的查询,并且它们永远不会相互阻止。
这并不意味着其他交易不必等待。特别是,DELETE
查询最终必须获取独占锁,并且如果SELECT
持有共享锁,则必须等待。通常这不是问题,因为引擎会尽快释放锁。当它成为一个问题时,你会想要查看像snapshot isolation这样的解决方案,它使用乐观并发和冲突检测而不是锁定。在该模型下,SELECT
将永远不会阻止任何其他查询(保存那些想要表锁的查询)。当然,这不是免费的;行版本控制是用来占用磁盘空间和I / O.