简体   繁体   English

事务可序列化隔离级别

[英]Transaction Serializable Isolation Level

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE; ALTER SESSION 设置 ISOLATION_LEVEL = SERIALIZABLE;

Question1 :问题1

T1 (transaction 1) and T2 (transaction 2) T1 (事务 1)和T2 (事务 2)

T1 : select * from tableName where status = 'A'; T1 : select * 来自 tableName where status = 'A';

T2 : insert into tableName(id, status) values (1, 'I'); T2 : 插入 tableName(id, status) 值 (1, 'I');

T2 : commit; T2 :提交;

T1 : select * from tableName where status = 'I'; T1 : select * 来自 tableName where status = 'I'; // Why T1 can not get the record with status I committed by T2 ? // 为什么T1不能得到T2提交的状态为I 的记录? Is this because the snapshot created by T1 and what's the scope of this snapshot, the whole table?这是因为T1创建的快照,这个快照的scope是什么,整个表?

Question2 :问题2

T1 : insert into tableName(id, status) values (1, 'I'); T1 : 插入 tableName(id, status) 值 (1, 'I');

T2 : insert into tableName(id, status) values (1, 'I'); T2 : 插入 tableName(id, status) 值 (1, 'I'); // T2 is blocked if id is unique. // 如果 id 是唯一的,则 T2 被阻塞。 Why T2 blocked?为什么T2被挡住了? Because as I know, both transactions create a snapshot, even they have not committed yet.因为据我所知,两个事务都会创建一个快照,即使它们还没有提交。

Are there any locks take the participant in this scenario?在这种情况下,参与者是否有任何锁? Thanks.谢谢。

T1: select * from tableName where status = 'I'; T1: select * from tableName where status = 'I'; // Why T1 can not get the record with status I committed by T2? // 为什么T1 不能得到T2 提交的状态为我的记录? Is this because the snapshot created by T1 and what's the scope of this snapshot, the whole table?这是因为T1创建的快照,这个快照的scope是什么,整个表?

Because SERIALIZE transaction can see the data committed before the transaction started or whatever changes made by the transaction itself.因为 SERIALIZE 事务可以看到在事务开始之前提交的数据或事务本身所做的任何更改。 That is why T1 is not able to see the Record I as it was inserted after the T1 transaction is started.这就是 T1 无法看到在 T1 事务启动后插入的记录 I 的原因。

Answering your second question,回答你的第二个问题,

T2: insert into tableName(id, status) values (1, 'I'); T2:插入 tableName(id, status) 值 (1, 'I'); // T2 is blocked if id is unique. // 如果 id 是唯一的,则 T2 被阻塞。 Why T2 blokced?为什么T2被封锁了? Becase as I known, both transaction create an snapshot and they even have not commit yet.因为我知道,两个事务都创建了一个快照,他们甚至还没有提交。

Even though both the transactions are SERIALIZE, Oracle maintains integrity and will not allow violating any constraint.即使两个事务都是 SERIALIZE,Oracle 保持完整性并且不允许违反任何约束。 So you can not add record I in your T2 transaction which violates any constraint.因此,您不能在违反任何约束的 T2 事务中添加记录 I。

  1. Is this because the snapshot created by T1这是因为 T1 创建的快照

yes是的

  1. and what's the scope of this snapshot, the whole table?这个快照的 scope 是什么,整张桌子?

SCN SCN

Question2: Why T2 blokced?问题2:为什么T2被阻塞了?

Because you have unique or primary key constraint and it's not deffered.因为您有唯一或主键约束并且它没有被延迟。

Following what SERIALIZABLE means:遵循 SERIALIZABLE 的含义:

SERIALIZABLE.可序列化。 This is generally considered the most restrictive level of transaction isolation, but it provides the highest degree of isolation.这通常被认为是最严格的事务隔离级别,但它提供了最高程度的隔离。 A SERIALIZABLE transaction operates in an environment that makes it appear as if there are no other users modifying data in the database. SERIALIZABLE 事务在使其看起来好像没有其他用户修改数据库中的数据的环境中运行。 Any row you read is assured to be the same upon a reread, and any query you execute is guaranteed to return the same results for the life of a transaction.确保您读取的任何行在重新读取时都是相同的,并且您执行的任何查询都保证在事务的生命周期内返回相同的结果。

Question 1问题 1

So in T1 you will not get any change made by T2, because your transaction level is SERIALIZABLE.所以在 T1 中你不会得到 T2 所做的任何更改,因为你的事务级别是 SERIALIZABLE。 That isolation level assures your query will always return the same results.该隔离级别可确保您的查询始终返回相同的结果。 Side effects, or changes, made by other transactions aren't visible to the query no matter how long it has been running.无论查询运行了多长时间,其他事务所做的副作用或更改对查询都是不可见的。

Serializable isolation is suitable for environments:可序列化隔离适用于环境:

  • With large databases and short transactions that update only a few rows大型数据库和仅更新几行的短事务
  • Where the chance that two concurrent transactions will modify the same rows is relatively low两个并发事务修改相同行的机会相对较低
  • Where relatively long-running transactions are primarily read only相对长时间运行的事务主要是只读的

Regarding your second question, the row will be locked after a commit is executed, but the row won't be visible for T2.关于您的第二个问题,执行提交后该行将被锁定,但该行对于 T2 不可见。

More information here and a good example:更多信息和一个很好的例子:

https://docs.oracle.com/cd/E25054_01/server.1111/e25789/consist.htm#BABCJIDI https://docs.oracle.com/cd/E25054_01/server.1111/e25789/consist.htm#BABCJIDI

Section 9.3 Read Consistency and Serialized Access Problems in Serializable Transactions 9.3 可序列化事务中的读一致性和序列化访问问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM