【发布时间】:2023-03-13 08:21:01
【问题描述】:
SQL 标准是否指定了多表查询的锁定顺序?
例如,给定:
SELECT department.id FROM permissions, terminals, departments WHERE department.id = ? AND terminal.id = ? AND permissions.parent = department.id AND permissions.child = terminals.id;
- SQL 标准是否保证锁定顺序,还是由(特定于实现的)执行计划确定?
- 有没有办法保证锁定顺序?
- 如果没有办法保证锁定顺序,我们应该如何防止死锁?
更新:请不要在未解释原因的情况下投票关闭此问题。就我而言,这是一个编程问题,这使它成为 Stackoverflow 的热门话题。如果您认为该问题需要进一步完善,请解释,我将非常乐意为您解答。
【问题讨论】:
-
SELECT 查询不会生成导致死锁的锁。您能否重新表述您的问题,使其与实际情况相关?
-
@GordonLinoff,READ_COMMITTED 中的 SELECT 查询确实会生成锁(但在语句期间)。对于其他隔离级别(例如 REPEATABLE_READ 或 SERIALIZABLE),它们会保留锁定直到事务结束。警告:一些数据库使用不使用任何锁的 MVCC,但这些超出了这个问题的范围。
-
锁是一个实现细节。隔离级别仅指定可以/不发生的现象。在 SQL Server 中,读取提交时的选择查询大多采用
S锁,一旦读取数据(在语句结束之前)就会释放这些锁。有时这些锁可以保留到语句结束,但是example 和其他时候它根本不需要行级S锁。除非您指定特定的 RDBMS,否则第 1 点和第 2 点和第 3 点是无法回答的。 -
READ_COMMITTED 隔离级别的查询使用共享读锁。我希望数据库可以在单个原子操作中获取所有必需的锁。提交可能会或可能不会阻止读取 - 我希望大多数企业数据库足够聪明以避免这种情况
-
@MartinSmith,请发布答案,以便我们更详细地阐述您的观点。