当多个对象持有一个共享锁并且一个想要升级到独占时,sql中基于锁的并发控制如何工作?

Posted

技术标签:

【中文标题】当多个对象持有一个共享锁并且一个想要升级到独占时,sql中基于锁的并发控制如何工作?【英文标题】:How does lock-based concurrency control in sql work when multiple objects hold a shared lock and one wants to upgrade to exclusive? 【发布时间】:2013-12-27 16:21:53 【问题描述】:

我试图了解事务如何与 sql 中的锁一起工作,并观看了this great tutorial on youtube。

我不明白如果 2 个不同的事务在同一个对象上获得共享锁,然后其中一个或两个想要升级到对象上的独占锁以写入它,会发生什么。

视频中 1:12:55 的示例会发生什么?

它是否会被归类为死锁并且其中一个事务是否必须回滚?他们中的一个肯定不能等待想要独占锁并移除它的共享锁,然后在第一个事务完成时继续,因为在事务结束之前无法移除锁可以吗?

干杯。

【问题讨论】:

您需要小心,这非常依赖于 RDBMS。不同的 RDBMS 以不同的方式实现锁定模型。您想到了哪种 RDBMS? 我正在为我正在进行的项目使用 mysql。我试图解决的具体问题,我认为现在已经解决了,在chat.***.com/rooms/44007/… 讨论 【参考方案1】:

想要独占锁的事务必须等到所有其他共享锁都被删除才能生效。在这种情况下,它会等待另一个事务释放它的共享锁,然后它会获得一个独占锁。

因此,如果另一个事务由于其他原因被初始事务阻止,这将导致死锁。因此,一个好的数据库设计应该尽量确保初始事务在等待排他锁时不会阻塞任何东西。

【讨论】:

因此,如果 t2 等到 t1 完成以释放所有其他共享锁,这是否意味着 t2 将继续,但它先前读取的对象 A 现在将不正确,因为 t1 更改了它在它提交和释放它的独占和共享锁之前? 如果 t2 在 t1 结束后继续,而不是从头开始,那么结果是不是和表中的结果一样,意思是最后的错误答案? 哦,等等,在这个例子中会出现死锁,因为在两个事务中都写入了同一个对象,是吗?如果 t1 实际上不需要写任何东西,那么它会正常工作,因为当 t2 恢复时,它正在查看的任何内容都不会改变值。干杯! @TomJenkinson - 是的,最坏的情况是死锁。但是,如果从未获得阻塞共享锁,则可以避免这种情况。排他读锁(在 mysql 中为 'SELECT ... FOR UPDATE')将完全跳过共享锁并避免此示例中的死锁。 那么共享锁是mysql中事务的默认值吗?或者默认情况下根本没有锁定?而且你在那个例子中说T1中的第一个R(A)应该是一个带有FOR UPDATE的选择,这会导致T2在它甚至可以读取A之前等待,直到第一个事务完成?我假设这个排他锁会一直保持到事务结束,然后像共享锁一样被释放?

以上是关于当多个对象持有一个共享锁并且一个想要升级到独占时,sql中基于锁的并发控制如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

独占锁 和 共享锁

深入理解AQS(二)- 共享模式

LiteOS 互斥锁机制

将共享锁升级为独占锁时避免 MySQL 死锁

并发编程—独占锁和共享锁

pthread之读写锁