跳转到主要内容
模块 11 · 第 4 课(共 4)课程中的44/57~12 min
模块课程(4/4)

隔离级别

除了明确的 FOR UPDATE 之外,交易还具有深入引擎的固有数学规则,这些规则控制默认情况下要花费多少能量来隔离每个单独的交互。 这称为隔离级别。在 SQL 世界中,我们知道 4 个标准标准,按功能和安全的顺序排列,但在性能方面显然相反。

  • READ UNCOMMITTED: 无政府主义的疯狂,您的交易将看到其他人所做的每一个更改,包括来自人们在自己的脚本中途进行的临时数据。由于脏读错误不断,没有人在大型数据库上使用它。
  • READ COMMITTED: (Postgres 的默认值)。一旦第三方发出 COMMIT,您将立即看到新数据,但您可能会成为幻读(在漫长的工作流程中途看到新记录)或非线性一致视图的受害者。
  • REPEATABLE READ: 较重。在您的大时间窗口会话期间,我“看到”数据库在我的查询开始时冻结,完全忽略甚至无视其他人完成的官方提交!它可以防止记录神奇地出现,保证稳定性。
  • SERIALIZABLE: 神级(超慢)。通过阻止它们并在单个通道中串行执行来处理每个重叠事务,无情地中止那些冲突的事务,从根本上消除甚至最轻微冲突的科学可能性,牺牲了 90% 的高吞吐量。

你如何设置它?

您输入的不是普通的 BEGIN; :

SQL
BEGIN ISOLATION LEVEL SERIALIZABLE;

-- and you proceed normally with your hermetically sealed isolation
UPDATE products SET stock = 10;
COMMIT;

或者在某些变体和较旧的引擎中,您可以在启动后分配它:

SQL
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

自己尝试一下

锻炼#sql.m11.l4.e1
尝试:0加载中...

启动一个事务,正式将查询生命周期的全局级别设置为 REPEATABLE READ,以创建冻结的、受保护的交换。\n请记住,在查询级别,除非后续执行其他操作,否则它没有任何作用,因此使用“COMMIT”将其关闭为空。

正在加载编辑器...
显示提示

使用 BEGIN ISOLATION LEVEL REPEATABLE READ 打开;并以 COMMIT 结束;

3 次尝试后可用的解决方案

锻炼#sql.m11.l4.e2
尝试:0加载中...

让我们尝试疯狂的可序列化级别并插入一些虚构的数据。\n打开一个“SERIALIZABLE”块。\n将类别 Id=2 的名称更新为“Nuovo Nome Segreto”。\n运行最终的原子解决提交。

正在加载编辑器...
显示提示

开始隔离级别可串行化;\n更新类别 SET name = 'Nuovo Nome Segreto' WHERE id = 2;\nCOMMIT;

3 次尝试后可用的解决方案