【发布时间】:2016-01-14 22:42:24
【问题描述】:
在数据库中,我们不希望在修改该表中的一行时删除该表。根据我的理解,在表中写入行时,对表的读锁+对行的写锁应该足够了(基于删除表时需要写锁),为什么在这种情况下我们需要意图锁?似乎很多数据库都使用了意图锁,这让我很困惑。我认为 pthread_rwlock 应该足够了。
【问题讨论】:
标签: database concurrency
在数据库中,我们不希望在修改该表中的一行时删除该表。根据我的理解,在表中写入行时,对表的读锁+对行的写锁应该足够了(基于删除表时需要写锁),为什么在这种情况下我们需要意图锁?似乎很多数据库都使用了意图锁,这让我很困惑。我认为 pthread_rwlock 应该足够了。
【问题讨论】:
标签: database concurrency
表上的读锁 + 行上的写锁
这会破坏桌子上read lock 的含义。
假设并发 SELECT 操作,在执行期间需要 未修改的表。此操作将对表进行读取锁定 ...并且它会在您的实施中成功。这很糟糕,因为表格实际上在行修改期间被修改了。
相反,跟随锁组合用于修改表中的行:
IX(Intent eXclusive) on table + X(eXclusive, similar to "write lock") on row
这种组合兼容(即可以同时执行)与另一行的修改,但它不兼容与
S(Share, similar to "read lock") on table
由 SELECT 使用。
可以在例如wiki 上找到锁兼容性表。
【讨论】:
我读到here,它们只是为了性能而存在。想象一下,您想删除一个表,但您必须检查每一行是否已锁定 - 这将非常耗时,并且您必须锁定您检查的每一行。
这是来自博客文章的引用:
从技术角度来看,意图锁并不是真正需要的 SQL 服务器。它们与性能优化有关。让我们 更详细地看一下。使用 Intent Lock SQL Server 在锁定层次结构中的更高级别表示您拥有 在其他地方获得了锁。意图共享锁告诉 SQL Server 其他地方有一个共享锁。意图更新或意图 排他锁也是如此,但这次 SQL Server 知道 某处有更新锁或排他锁。它只是一个 指示,仅此而已。
但该指示如何帮助 SQL Server 提高性能 优化?想象一下,您想在 表层。在这种情况下,SQL Server 必须知道是否存在 不兼容的锁(如共享锁或更新锁) 记录。如果没有意向锁,SQL Server 将不得不检查每个 记录以查看是否已授予不兼容的锁。
但是在表级别使用 Intent Shared Lock,SQL Server 知道 立即在其他地方授予共享锁,并且 因此无法在表级别授予排他锁。 这就是 SQL Server 中存在 Intent Locks 的全部原因:允许 有效检查是否存在不兼容的锁 锁定层次结构。很简单,不是吗?
【讨论】:
今天的一个结论是“意图锁定可以以更便宜/更安全的方式以只读模式锁定父节点及其所有子节点”。
举个例子,表的只读情况,如何在S-X模式下锁定?
我们将表锁定在 S 模式,然后用户仍然可以用 S(table) + W(row) 的方式修改行。为避免这种情况,我们需要将每一行锁定为 S 模式,以确保不会更新行。成本如此之大,而且它有一个错误,用户也可以插入新行。 -- 成本太高而且不安全。
我们将表锁定在 X 模式下,其他人如何读取行(表上的 S + 行上的 S),没办法,因为表上的 mode_X 阻塞了表上的 MODE_S。那不是只读的。
使用意图锁的正确解决方案是:
在 MODE_S 中锁定表。就这样!
任何修改行的意图都需要对表进行 MODE_IX 锁,但它会被 MODE_S 阻止。该解决方案便宜/高效且安全!
【讨论】: