悲观锁定与可串行化事务隔离级别

22

我对实体锁定和事务隔离级别的目的有点了解,但是无法区分悲观锁定和可串行化级别之间的区别。据我所知,在两种情况下,表格都会被锁定,没有其他事务可以访问它,因此在这两种情况下,数据库采取措施防止并发修改,看起来没有区别。请问是否确实存在差异?


@pringi,我的问题中没有解释这两者的区别。 - Leonid Bor
抱歉。这个:https://dev59.com/VWEh5IYBdhLWcg3wPRWq - pringi
@pringi,使用锁定机制,我将无法从表中读取数据;而使用可序列化级别,在两个并行事务的情况下,我将能够读取但无法写入数据? - Leonid Bor
“在这两种情况下,表格都会被锁定…” 这通常在任何一种情况下都不是真的。 - Mike Sherrill 'Cat Recall'
3个回答

12

我不假设你正在使用ObjectDB。如果您编辑问题并包括您在JPA中使用的特定数据库,则可能会得到更好的答案。

我不喜欢“乐观锁定”和“悲观锁定”这些术语。我认为“乐观并发控制”和“悲观并发控制”更准确。锁是处理并发控制问题最常见的方法,但它们不是唯一的方法。(Date在《数据库系统导论》中关于并发的章节大约有25页。)

“事务管理”和“并发控制”的主题不限于数据的关系模型或SQL数据库管理系统(DBMS)。事务隔离级别与SQL有关。

“悲观并发控制”实际上只意味着您期望DBMS在处理您的请求时阻止其他事务访问“某些东西”。行为取决于DBMS供应商。不同的供应商可能通过锁定整个数据库、锁定某些表、锁定某些页面或锁定某些行来防止访问。或者,DBMS可能以其他一些不直接涉及锁的方式防止访问。

事务隔离级别是SQL尝试解决并发控制问题的方式。事务隔离级别在SQL标准中定义。

“串行化”事务隔离级别保证并发的可串行化事务的效果与以某种特定顺序逐个运行它们的效果相同。该保证描述了“效果”——不涉及任何特定的并发控制或锁定方式,以“实现”该效果。


基本上,当我通过SQL设置事务隔离级别时,它是一种指令,告诉数据库管理系统以特定的方式处理我的操作,这似乎与悲观并发控制相同,不是吗? - Leonid Bor
2
@LeonidBor:这样想吧。乐观并发控制和悲观并发控制给你两个选择。SQL事务隔离级别给你四个选择。"并发"是一个话题;"事务隔离级别"是另一个话题。试图直接将并发映射到事务隔离级别可能会在长期运行中引起麻烦。特别是因为事务隔离级别是用否定的方式定义的——不会发生的事情。 - Mike Sherrill 'Cat Recall'

8

悲观锁通常涉及对数据库进行写入锁,以安全和独占的方式进行更改。这通常是通过执行select ... for update来完成的。这将阻止或延迟其他连接在第一个连接的事务完成之前对已锁定记录进行select ... for update或更改。

可串行化隔离级别不需要关注更改,但确保在事务开始后,读取的结果始终保持不变(除了事务本身的更改),直到该事务结束。为了支持这一点,“非MVCC” -DBMS必须在数据库中设置许多锁(在由串行工作的连接读取的每个记录上),因此可能会严重影响并发性。

当数据库提供MVCC时,如Oracle,MySql-INNODB,MariaDB,Postgres,也可以在不锁定的情况下实现同样的效果。


0
隔离级别是对事务中可见数据的限制。
只有在提交之前没有其他事务更改数据时,可串行化隔离才会成功。其内在实现不应产生死锁。
可串行化隔离由于需要进行额外的检查以确保一致性,因此代价较高。因此,使用较少限制的隔离级别,并通过悲观/乐观锁定来同步对关键部分的访问。 悲观锁是尝试锁定资源,否则事务将失败。这是从事务角度看的“快速失败”模式,也是死锁的真正源头。这不是事务隔离,而是一种对并发访问数据库内容进行同步的方式。 乐观锁实际上并不是一种锁,而只是在提交之前进行版本检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接