Sqlserver_Oracle_Mysql_Postgresql不同数据库之隔离级别介绍

官方文档
Sqlserver https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-ver16
Mysql https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_isolation_level
Oracle https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/data-concurrency-and-consistency.html#GUID-2A0FDFF0-5F72-4476-BFD2-060A20EA1685
Postgresql https://www.postgresql.org/docs/14/transaction-iso.html

读提交(READ COMMITTED),简称RC:根据数据库的多版本并发控制(MVCC)机制,不同时刻启动的事务会有不同的一致性读视图consistent read view,在“读提交”隔离级别下,这个视图是在每个SQL语句开始执行的时候创建的,其他事务可以在当前事务的各个语句之间更改数据。oracle,sqlserver,postgresql(show transaction_isolation;)的隔离级别默认就是读提交。隔离级别比可重复读(REPEATABLE READ)要低一点,并发级别比可重复读(REPEATABLE READ)要高一点。

可重复读(REPEATABLE READ),简称RR:根据数据库的多版本并发控制(MVCC)机制,不同时刻启动的事务会有不同的一致性读视图consistent read view,在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图,其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据。mysql(select @@global.tx_isolation)的隔离级别默认就是可重复读,oracle没有这个隔离级别的概念。

未提交读(READ UNCOMMITED):脏读,一个事务还没提交时,它做的变更就能被别的事务看到;是最低的隔离级别,并发级别最高。

可序列化(SERIALIZABLE):在当前事务完成之前,其他事务不能使用当前事务中任何语句读取的键值插入新行。注意其中的关键字任何语句,意思就是读也会锁定行,也就是说对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。限制最多的隔离级别,因为它锁定了当前事务涉及到的所有行,当前事务完成之前会一直保持这些行范围锁,并发级别最低。

并发级别从高到低排序:未提交读(READ UNCOMMITED)—>读提交(READ COMMITTED)—>可重复读(REPEATABLE READ)—>可序列化(SERIALIZABLE)

其中比较容易混淆的就是读提交(READ COMMITTED)和可重复读(REPEATABLE READ),读提交(READ COMMITTED)和可重复读(REPEATABLE READ)的区别就是:读提交(READ COMMITTED)的一致性读视图consistent read view是在每个SQL语句开始执行的时候创建的,可重复读(REPEATABLE READ)的一致性读视图consistent read view是在事务启动时创建的。其中Sqlserver、Mysql、PG都有这两种隔离级别,Oracle只有读提交(READ COMMITTED)但是没有可重复读(REPEATABLE READ)的概念,oracle的Read consistency(select才会产生)和Read current(dml才会产生)其实都是读提交隔离级别。Read consistency,当查询开始的时候oracle将确立一个时间点,凡是在这个时间点以前提交的数据oracle将能看见,之后提交的数据将不能看见。但查询的时候可能遇上这样的情况,该块中数据已经被修改了,没有提交,或者提交的时间点比查询开始的时间晚,则oracle为了保证读的一致性,需要去回滚段获取该块中变化前的数据。Read current,就是看到当前的block中的内容是什么就是什么,跟时间点无关,不能去回滚段获取之前的数据。假如当前block中数据是被其他的session更改过还没有提交,那么则看到当前状态数据被其他session锁定,则dml需要等待其他session结束(提交或回滚),这样这个dml就会被堵塞。更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read),总是读取已经提交完成的最新版本。

隔离级别和大事务在主从节点的延迟是否有重大关系,个人认为关系不大,主要和同步逻辑相关相关,如果主库上必须等所有事务执行完成才会写入日志,并且日志文件需要传输到备库再在备库应用完这些日志,才能完成同步,这样主从的延迟就是:日志从主库传输到备库+日志在备份的应用时间。所以说如果一个主库上的事务执行 10 分钟,那这个事务是否就会导致从库延迟 10 分钟?这句话的理解需要针对不同数据库来说,针对sqlserver和oracle而言就不会延迟10分钟,因为sqlserver和oracle主节点的事务不是非要提交了才会写入日志,针对mysql是对的,因为mysql的同步用的是bin-log,而mysql事务不能跨bin-log,也就是mysql事务完成了才会写入bin-log文件,如果mysql事务在主节点需要10分钟,那么从事务开始到事务结束这10分钟之后才会写入binlog文件,也就是10分钟之后从库才会真正开始应用主库的binlog,这就延迟了10分钟

Sqlserver
READ COMMITTED
Specifies that statements cannot read data that has been modified but not committed by other transactions. This prevents dirty reads. Data can be changed by other transactions between individual statements within the current transaction, resulting in nonrepeatable reads or phantom data. This option is the SQL Server default.
指定语句不能读取已由其他事务修改但尚未提交的数据。 这样可以避免脏读。 其他事务可以在当前事务的各个语句之间更改数据,从而产生不可重复读取和虚拟数据。 该选项是 SQL Server 的默认设置。

REPEATABLE READ
Specifies that statements cannot read data that has been modified but not yet committed by other transactions and that no other transactions can modify data that has been read by the current transaction until the current transaction completes.
Shared locks are placed on all data read by each statement in the transaction and are held until the transaction completes. This prevents other transactions from modifying any rows that have been read by the current transaction. Other transactions can insert new rows that match the search conditions of statements issued by the current transaction. If the current transaction then retries the statement it will retrieve the new rows, which results in phantom reads. Because shared locks are held to the end of a transaction instead of being released at the end of each statement, concurrency is lower than the default READ COMMITTED isolation level. Use this option only when necessary.
指定语句不能读取已由其他事务修改但尚未提交的行,并且指定,其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据。
对事务中的每个语句所读取的全部数据都设置了共享锁,并且该共享锁一直保持到事务完成为止。 这样可以防止其他事务修改当前事务读取的任何行。 其他事务可以插入与当前事务所发出语句的搜索条件相匹配的新行。 如果当前事务随后重试执行该语句,它会检索新行,从而产生虚拟读取。 由于共享锁一直保持到事务结束,而不是在每个语句结束时释放,因此并发级别低于默认的 READ COMMITTED 隔离级别。 此选项只在必要时使用。

Mysql
READ COMMITTED
An isolation level that uses a locking strategy that relaxes some of the protection between transactions, in the interest of performance. Transactions cannot see uncommitted data from other transactions, but they can see data that is committed by another transaction after the current transaction started. Thus, a transaction never sees any bad data, but the data that it does see may depend to some extent on the timing of other transactions.
When a transaction with this isolation level performs UPDATE … WHERE or DELETE … WHERE operations, other transactions might have to wait. The transaction can perform SELECT … FOR UPDATE, and LOCK IN SHARE MODE operations without making other transactions wait.
一种使用锁定策略的隔离级别,为了提高性能,放宽事务之间的一些保护。事务看不到其他事务未提交的数据,但可以看到当前事务启动后另一个事务提交的数据。因此,事务永远不会看到任何坏数据,但它确实看到的数据可能在某种程度上取决于其他事务的时间。
当具有此隔离级别的事务执行 UPDATE … WHERE 或 DELETE … WHERE 操作时,其他事务可能必须等待。该事务可以执行 SELECT … FOR UPDATE 和 LOCK IN SHARE MODE 操作,而无需让其他事务等待。

REPEATABLE READ
The default isolation level for InnoDB. It prevents any rows that are queried from being changed by other transactions, thus blocking non-repeatable reads but not phantom reads. It uses a moderately strict locking strategy so that all queries within a transaction see data from the same snapshot, that is, the data as it was at the time the transaction started.
When a transaction with this isolation level performs UPDATE … WHERE, DELETE … WHERE, SELECT … FOR UPDATE, and LOCK IN SHARE MODE operations, other transactions might have to wait.
InnoDB 的默认隔离级别。它可以防止查询的任何行被其他事务更改,从而阻止不可重复读取,但不会阻止幻读。它使用适度严格的锁定策略,以便事务中的所有查询都看到来自同一快照的数据,即事务开始时的数据。
当具有此隔离级别的事务执行 UPDATE … WHERE、DELETE … WHERE、SELECT … FOR UPDATE 和 LOCK IN SHARE MODE 操作时,其他事务可能必须等待。

Oracle
Oracle Database provides the transaction isolation levels:
Read Committed Isolation Level
Serializable Isolation Level
Read-Only Isolation Level

Read Committed Isolation Level
In the read committed isolation level, every query executed by a transaction sees only data committed before the query—not the transaction—began.
This isolation level is the default. It is appropriate for database environments in which few transactions are likely to conflict.
A query in a read committed transaction avoids reading data that commits while the query is in progress. For example, if a query is halfway through a scan of a million-row table, and if a different transaction commits an update to row 950,000, then the query does not see this change when it reads row 950,000. However, because the database does not prevent other transactions from modifying data read by a query, other transactions may change data between query executions. Thus, a transaction that runs the same query twice may experience fuzzy reads and phantoms.
在读取已提交隔离级别中,事务执行的每个查询只能看到在查询开始之前提交的数据,而不是事务开始。
这个隔离级别是默认的。它适用于很少有事务可能发生冲突的数据库环境。
读取提交事务中的查询避免读取在查询进行时提交的数据。例如,如果一个查询正在扫描一个百万行的表,并且如果另一个事务提交了对第 950,000 行的更新,那么查询在读取第 950,000 行时不会看到此更改。但是,由于数据库不会阻止其他事务修改查询读取的数据,因此其他事务可能会在查询执行之间更改数据。因此,两次运行相同查询的事务可能会遇到模糊读取和幻像。
Read Consistency in the Read Committed Isolation Level
The database provides a consistent result set for every query, guaranteeing data consistency, with no action by the user.
An implicit query, such as a query implied by a WHERE clause in an UPDATE statement, is guaranteed a consistent set of results. However, each statement in an implicit query does not see the changes made by the DML statement itself, but sees the data as it existed before changes were made.
If a SELECT list contains a PL/SQL function, then the database applies statement-level read consistency at the statement level for SQL run within the PL/SQL function code, rather than at the parent SQL level. For example, a function could access a table whose data is changed and committed by another user. For each execution of the SELECT in the function, a new read-consistent snapshot is established.
读取提交隔离级别中的读取一致性
数据库为每次查询提供一致的结果集,保证数据的一致性,无需用户进行任何操作。
隐式查询(例如 UPDATE 语句中的 WHERE 子句隐含的查询)保证获得一致的结果集。但是,隐式查询中的每个语句都看不到 DML 语句本身所做的更改,而是看到更改前存在的数据。
如果 SELECT 列表包含 PL/SQL 函数,那么数据库会在语句级别为 PL/SQL 函数代码内运行的 SQL 应用语句级别的读取一致性,而不是在父 SQL 级别。例如,一个函数可以访问一个表,该表的数据已被另一个用户更改和提交。对于函数中的每一次 SELECT 执行,都会建立一个新的读一致性快照。

read committed isolation level
An isolation level that guarantees that a query executed by a transaction sees only data committed before the query—not the transaction—began.
Oracle Database offers the read committed (default) and serializable isolation levels. Also, the database offers a read-only mode.
一种隔离级别,它保证事务执行的查询只能看到在查询(而不是事务)开始之前提交的数据。
Oracle 数据库提供已提交读(默认)和可序列化隔离级别。此外,数据库提供只读模式。

PG
Read Committed Isolation Level
Repeatable Read Isolation Level
Serializable Isolation Level

Read Committed is the default isolation level in PostgreSQL. When a transaction uses this isolation level, a SELECT query (without a FOR UPDATE/SHARE clause) sees only data committed before the query began; it never sees either uncommitted data or changes committed during query execution by concurrent transactions. In effect, a SELECT query sees a snapshot of the database as of the instant the query begins to run. However, SELECT does see the effects of previous updates executed within its own transaction, even though they are not yet committed. Also note that two successive SELECT commands can see different data, even though they are within a single transaction, if other transactions commit changes after the first SELECT starts and before the second SELECT starts.
Read Committed 是 PostgreSQL 中的默认隔离级别。当事务使用此隔离级别时,SELECT 查询(没有 FOR UPDATE/SHARE 子句)只能看到在查询开始之前提交的数据;它永远不会看到未提交的数据或并发事务执行查询期间提交的更改。实际上,SELECT 查询看到的是查询开始运行时的数据库快照。然而,SELECT 确实看到了在它自己的事务中执行的先前更新的影响,即使它们尚未提交。另请注意,如果其他事务在第一个 SELECT 开始之后和第二个 SELECT 开始之前提交更改,则两个连续的 SELECT 命令可以看到不同的数据,即使它们在单个事务中也是如此

The Repeatable Read isolation level only sees data committed before the transaction began; it never sees either uncommitted data or changes committed during transaction execution by concurrent transactions. (However, the query does see the effects of previous updates executed within its own transaction, even though they are not yet committed.) This is a stronger guarantee than is required by the SQL standard for this isolation level, and prevents all of the phenomena described in Table 13.1 except for serialization anomalies. As mentioned above, this is specifically allowed by the standard, which only describes the minimum protections each isolation level must provide.
Repeatable Read 隔离级别只能看到事务开始前提交的数据;它永远不会看到未提交的数据或并发事务在事务执行期间提交的更改。 (但是,查询确实看到了在它自己的事务中执行的先前更新的影响,即使它们尚未提交。)这是比 SQL 标准对此隔离级别所要求的更强的保证,并且可以防止所有现象除序列化异常外,如表 13.1 所述。如上所述,这是标准明确允许的,它只描述了每个隔离级别必须提供的最低保护。

你可能感兴趣的:(数据库,oracle,postgresql)