数据库事务和锁定之间的确切关系是什么?


16

本着提高我的知识水平提出的一个谦虚的问题。请您反应温和。

作为长期的应用程序开发人员,我在某种程度上知道事务是什么(我一直都在使用它们)。暂时不考虑事务隔离级别,在较高的级别上,事务允许一个工作块完全或根本不完成,并允许与其他数据库修改活动进行一定程度的隔离。

我还知道什么是锁(在各种数据库中),或者至少是一种行为(如果我以某种方式明确地锁定了一个表,那么任何其他进程或线程都无法更新该表的任何内容)。

我现在最明显的明确的是:在各种数据库中,当我明确地锁定一行或一台,我在用人所使用的数据库的交易设施在幕后进行交易正常工作完全一样的结构?

也就是说,对我来说,为了使事务是原子的和隔离的,它必须进行一些锁定。这种由事务启动,隐藏迁移的锁定是否与各种数据库允许我通过诸如SELECT FOR UPDATE或显式LOCK命令之类的构造访问的锁定相同?还是这两个概念完全不同?

再次,我为这个问题的天真道歉。我很高兴被告知更多的基础资料。

Answers:


12

当我显式锁定行或表时,我是否采用与数据库事务处理所使用的完全相同的构造来使事务正常工作?

是。如果那不是真的,那么您自己的“锁定”将仅适用于其他类似的“锁定”,而不会与引擎自身的锁定相互作用。因此,您将锁定表中的一行,这样它就不能被其他应用程序以相同的方式锁定,但是您的锁定将被引擎本身忽略。很少需要这些语义。在大多数情况下,应用程序锁定行意味着“将其锁定为禁止任何访问/修改方式”。旁注,确实存在严格针对应用程序的锁定机制,因为它们很有用。例如,SQL Server具有应用程序锁

在我看来,为了使事务是原子的和孤立的,它必须进行一些锁定。

锁定是实现此目的的一种方法。主要替代方法是版本控制。如今,大多数数据库都支持这两种方式(这也意味着,如果您“锁定”应用程序中的一行,但另一个事务使用版本控制来读取该行,则它将读取该行,因为您的锁定不会阻止版本控制的读取)。

您正在绕过数据库实现世界中称为“两阶段锁定协议”的概念。链接的Wikipedia文章是一个很好的入门。如果您想阅读有关此主题的更多详细说明,建议您去图书馆,并索取有关“ 事务处理:概念和技术”的贷款。几乎每个数据库的核心都是该书的实现。


也许你可以添加有关(无锁)乐观并发控制
ypercubeᵀᴹ

啊哈!现在我们在说话。确实,潜伏在我心中的是MVCC。感谢您的明确回答,大量参考资料以及抽出宝贵时间深入研究我的问题。
Laird Nelson

3

在回答问题之前需要一些背景知识:

注意:这与Microsoft SQL Server-RDBMS .......有关。

  • 用非常简单的术语来说,事务是一系列工作,必须整体上作为一个逻辑单元执行,并且必须维护ACID属性。
  • 任何RDBMS都必须提供“锁定工具”,以通过保留事务隔离及其持久性来整体上完成事务。这样可以确保数据库的物理完整性。
  • 最重要的是,默认情况下-事务在连接级别进行管理。因此,当在连接上启动事务时,在该连接上执行的所有T-SQL语句(S / I / U / D)都是事务的一部分,直到事务结束。(对MARS的处理方式不同)

现在回到您的问题:

当我显式锁定行或表时,我是否采用与数据库事务处理所使用的完全相同的构造来使事务正常工作?

是。这意味着您必须谨慎确定要修改的数据序列,并使数据库保持一致状态。换句话说,您的DML操作应使数据库处于一致状态,该状态限于组织的业务规则。尽管如此,RDBMS(此处为SQL Server)仍可以强制事务的物理完整性。

来自BOL:锁定和行版本控制可防止用户读取未提交的数据,并防止多个用户尝试同时更改同一数据。如果没有锁定或行版本控制,则针对该数据执行的查询可能会通过返回尚未在数据库中提交的数据而产生意外结果。

这种由事务启动的隐藏事务的锁定是否与各种数据库允许我通过诸如SELECT FOR UPDATE或显式LOCK命令之类的结构访问的锁定相同?

sql server中的所有内容都包含在一个事务中。当您访问数据时,RDBMS必须根据隔离级别和您对数据执行的操作来锁定。检查答案以获取更多详细信息。

一些很好的参考:


2

我想说事务是数据库“接口”的一部分,从某种意义上说,您作为开发人员可以决定何时开始,结束,在事务范围内做什么等。据我所知,锁属于实现细节。并用于对不同对象的访问同步。在大多数情况下,引擎自己决定锁定什么以及锁定多长时间。有许多无法直接操纵的系统级别锁(例如,引擎可能会锁定某些内存区域)。即使涉及DML锁,许多锁还是在后台发生(例如,为了确保Oracle的参照完整性,据我所记得,如果将新记录插入到SQLServer中,SQLServer可能会将锁锁定在主表中的相应行上)详细信息表)作为交易中发布的DML语句的结果。

对于事务,您可以从任何声称遵守SQL和支持事务的RDMS中获得或多或少的一致行为,但是在锁方面,几乎每个供应商都使用不同的策略和术语。据我所知,所有RMDS的共同点是事务之间的并发是由隔离级别定义的,而锁之间的并发是由锁类型(共享,互斥等)控制的。

总而言之,锁是控制对象一致性和并发性的低级机制。可以在SQL语句执行期间发出锁。根据事务隔离级别的实现,引擎可能会对受影响的对象(行,行组,索引等)施加不同类型的锁。没有可用手动问题锁(数量有限命令SELECT FOR UPDATELOCK)。DML锁可以升级(取决于RDMS,例如,在SQLServer row-> page-> partition-> table中)。数据库引擎还可以在连接初始化,备份,还原,过程/触发器/功能/等重新编译,启动,关闭等过程中发出锁。

我不确定是否能回答您的问题,但我希望这是有道理的。


感谢您的评论。到目前为止,您绝对是最接近的。我仍在尝试查看是否始终根据显式LOCKSELECT FOR UPDATE语句使用的锁或通过其他某种机制来实现事务。
Laird Nelson

据我所知,BEGIN TRANSACTION它本身不会发出锁。锁将在事务内的DML之后出现。
a1ex07 2014年

澄清-我的意思是BEGIN TRANSACTION本身不会创建DML锁;它其实应该发行一些内部锁,因为它来分配资源,添加到系统表[S](如果有的话)保持活跃交易等条目
a1ex07

1

我将使用SQL Server行话,但其他供应商的概念应相同:

您执行的每个命令都在事务内部执行。该事务可以使用BEGIN TRAN显式打开,也可以通过数据库引擎隐式打开。打开隐式事务的原因是引擎仍然需要保持ACID合规性和回滚能力。

当您执行SELECT FOR UPDATE时,这仅意味着在执行事务时,它将持有一定的锁定。


感谢您的评论。我知道的那么多。但是我的问题仍然是:打开该事务时,是否通过持有自己的锁来实现隔离?如果是这样,这些锁是否与我可以显式获得的锁相同?还是通过其他方式实现隔离?
Laird Nelson

2
是的,这是相同的机制。两种模式下的锁都可以实现隔离,您可以显式获取相同的锁。区别在于,如果不显式打开事务,则在命令完成时将释放锁,而在显式事务中,锁将保留到您提交为止(由于隔离级别,因此不是100%准确,但这就是大概的概念)。
Matan Yungman 2014年

感谢您的评论。我问我的问题的原因是,我读到某处某些数据库使用MVCC作为实现ACID事务的方式,在我看来,这是一种无锁的方式。那么,在这种情况下,我不清楚何时可以明确地发出锁定。但这可能是一个单独的问题。:-)
Laird Nelson

@LairdNelson是SQL Server 的快照隔离级别。现有的,但不是默认的并发机制。但是,它是Oracle或Postgresql的默认值,即IIRC。
玛丽安

0

锁是必需的,它们使数据库成为可能。这样可以防止当多个用户尝试读取而其他人向数据库写入数据时数据被破坏或无效。事务隔离通常是通过锁定事务中访问的任何内容来实现的。不良的设计应用程序大量使用了数据库锁定概念:)!因此,避免将锁定集中在FK和数据布局上。

一切都与ACID有关: -阅读此书,您的想法会清除!ACID是修改数据库时要应用的一组属性。

  • **原子性
  • 一致性
  • 隔离
  • 耐用性**

事务是一组相关的更改,用于实现某些ACID属性。事务是实现ACID属性的工具。

原子性意味着您可以保证所有交易都会发生,或者没有任何交易发生。您可以将一个或多个组件作为一个整体来执行复杂的操作,而崩溃,电源故障,错误或其他任何事情都不会使您处于仅发生某些相关更改的状态。

一致性意味着您保证数据将保持一致;您对相关数据的任何约束都不会被违反。

隔离意味着一个事务无法从另一个尚未完成的事务读取数据。如果两个事务正在同时执行,则每个事务都将像按顺序执行一样看待整个世界,并且如果一个事务需要读取另一事务写入的数据,则必须等到另一个事务完成为止。

持久性意味着一旦事务完成,就可以确保所有更改都已记录到持久性介质(例如硬盘)上,并且同样记录了事务已完成的事实。

因此,交易是保证这些特性的一种机制。它们是将相关动作组合在一起的一种方式,这样,从整体上讲,一组操作可以是原子的,可以产生一致的结果,可以与其他操作隔离开来,并且可以进行持久记录。


谢谢你的评论。我至少很了解ACID的属性。我仍然不清楚的是:事务是通过使用我可以通过显式LOCK语句直接使用的相同类型的锁来实现ACID的,还是它们是使用其他某种机制来实现的?
Laird Nelson

数据库提供许多事务隔离级别,这些级别控制选择数据时发生的锁定程度。可序列化,可重复读取,已提交读取,未提交读取。
Up_One 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.