Locking 关于DBMS锁定的澄清

Locking 关于DBMS锁定的澄清,locking,database,Locking,Database,我在上数据库管理系统的入门课,有一个问题我的书没有回答。这个问题不是来自我的家庭作业,我只是好奇 教科书不断强调事务是一个逻辑工作单元。然而,当遇到共享/独占锁定模式时,我有点困惑 书中有一个图表,看起来像这样: 时间|交易状态 1请求锁 2接收锁 3处理事务 4释放锁 5锁已释放 事务是同时处理的,还是在获得单个锁时处理的 如果在两个事务中有导致共享锁和独占锁的命令,那么这些事务是同时运行的,还是一个接一个地安排的?如果它需要独占锁,它将阻止另一个事务,或者在获得锁之前等待另一个事务完成 当其

我在上数据库管理系统的入门课,有一个问题我的书没有回答。这个问题不是来自我的家庭作业,我只是好奇

教科书不断强调事务是一个逻辑工作单元。然而,当遇到共享/独占锁定模式时,我有点困惑

书中有一个图表,看起来像这样:

时间|交易状态

1请求锁

2接收锁

3处理事务

4释放锁

5锁已释放

事务是同时处理的,还是在获得单个锁时处理的


如果在两个事务中有导致共享锁和独占锁的命令,那么这些事务是同时运行的,还是一个接一个地安排的?

如果它需要独占锁,它将阻止另一个事务,或者在获得锁之前等待另一个事务完成


当其他任何操作正在访问数据时,不可能发生需要独占锁(更新/删除/等)的事情。

实际上,每个操作都会在继续之前获得所需的锁。SELECT将首先获取行上的共享锁,然后读取该行。更新将首先获取该行上的独占锁,然后更新该行。理论上,你可以说“锁是获得的,然后事务处理”,但在现实生活中,事务中的每个操作都知道需要什么锁。

答案通常是,“这取决于”:

一般来说,你不需要在开始之前把所有的锁都取出来;但是,在释放任何锁之前,您需要取出所有锁。 因此,您可以执行以下操作:

lock resource A
update A
lock resource B
update B
unlock A
unlock B
这允许您对可能希望读取B的其他事务更友好一些,例如,不关心a。它确实带来了更多的风险——您可能无法获得B的锁,并决定回滚您的交易。休息时间到了

您还希望始终以相同的顺序获取所有锁,这样就不会陷入死锁(事务1有A,想要B;事务2有B,想要A;正午对峙,没有人赢。如果您执行一致的命令,事务2将尝试在B之前获得A,然后等待,让事务2继续进行,或者失败,如果事务1已经启动——无论哪种方式,都没有死锁)


当您打算排除锁时,事情会变得更有趣——这些锁被视为共享的,并带有一个“选项”使其成为独占的。这可能会在您的书后面的某个地方介绍:-)

一般来说,锁是在运行时确定的。处理
begintransaction
命令时,事务中还没有运行任何东西,因此没有锁。在事务锁中执行的命令被获取。

如果在两个事务中有命令导致共享锁和独占锁,那么这些事务是同时运行的,还是一个接一个地安排

锁不仅仅包含“共享/独占”的概念。关于锁,最重要的是它所应用的资源

两个事务(例如,两个单独的表,或两个单独的分区,或两个单独的页面,或两个单独的行,或两个单独的打印机,或两个单独的IP端口,…)可以继续并发运行而不会出现任何问题

只有当事务请求某个资源上的锁时,事务序列化才变得必要,而该锁的共享模式与某个其他事务在同一资源上持有的锁不兼容


如果你的教科书真的给出了你所说的事件的顺序,那就扔掉它。锁请求是在事务处理过程中出现的,事务处理者在事务开始时没有确定的最终方法来知道需要哪些锁(否则死锁将是不存在的问题)。

,除非事务中有所有相关的锁,否则不会发生任何事情?这不完全正确,因为按照操作顺序获取锁可能导致死锁。考虑{更新A;更新B;}和{Update B;更新A;}它们将永远互相等待,或者两者都超时。@方块:你建议在实践中,在现实生活中,DBMS是无死锁的吗?我的建议是,导致死锁并需要死锁检测来跳出两个事务的算法应该被认为是一个有漏洞的bug,需要黑客来掩盖它。这可能是一种权宜之计(易于实现与纠正真实问题等),但它是一个bug。我想微软不是这么看的。@Square:对。微软的懒散散漫程序员与Sybase、DB2、Tandem、PostgreSQL、InnoDB等公司的其他懒散团队签订的协议是否让世界陷入僵局……你只是嫉妒罢了我的答案被接受了;)。只是开玩笑。感谢你教育我什么是公认的行业惯例。人们倾向于处理死锁而不是避免死锁,这似乎违反直觉,但我想一定有原因。