事务隔离级别


并发读问题

 

【第一类更新丢失】撤销时,覆盖更新数据。

【脏读】读到未提交的更新。待定状态。

【虚读】其他事务已提交的插入数据。事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。

【不可重复读】未避免“随时更新”。一个事务对同一行数据重复读取两次,但是却得到了不同的结果。两次读取之间该数据被其它事务所修改。

【第二类丢失更新】覆盖已提交的更新

3.1.        第一类丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。
3.2.        脏读:一个事务读到另一个事务未提交的更新数据。
3.3.        幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
3.4.        不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
3.5.        第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据。


虚读
        事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
幻读(Phantom Reads)
        事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的 SQL语句相同)。这是因为 在两次查询过程中有另外一个事务插入数据造成的。


【隔离级别】

1)未提交读(Read Uncommitted):SELECT语句以非锁定方式被执行,所以有可能读到脏数据,隔离级别最低。

允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过 “排他写锁”实现。
 

2)提交读(Read Committed):【看到插入,看到更新】解决了脏读,但未解决不可重复读。

允许不可重复读取,但 不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。
——读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

在trasaction A中读取数据时对记录添加共享锁,但读取结束立即释放。其它transaction B对这个记录的试图修改会一直等待直到A中的读取过程结束,而不需要整个trasaction A的结束。所以,在trasaction A的不同阶段对同一记录的读取结果可能是不同的。

可能发生的问题:不可重复读。

 

3)可重复读(Repeated Read):【看到插入,看不到更新】

在同一个事务内的查询都是事务开始时刻一致的,InnoDB的默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻读。这可以通过“共享读锁”和“排他写锁”实现。

对于读出的记录,添加共享锁直到transaction A结束。其它transaction B对这个记录的试图修改会一直等待直到trasaction A结束。

可能发生的问题:当执行一个范围查询时,可能会发生幻读(插入)。

——读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
 

4)串行读(Serializable):完全的串行化读,所有SELECT语句都被隐式的转换成SELECT ... LOCK IN SHARE MODE,即读取使用表级共享锁,读写相互都会阻塞。隔离级别最高。

如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把 数据库系统的隔离级别设为 Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致 不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用 悲观锁或 乐观锁来控制。

添加范围锁(比如表锁,页锁等,关于range lock,我也没有很深入的研究),直到transaction A结束。以此阻止其它trasaction B对此范围内的insert,update等操作。

幻读,脏读,不可重复读等问题都不会发生。

隔离级别设置

select @@tx_isolation

set transaction isolation level read committed;

set global transaction isolation level read committed;

1)服务启动选项--transaction-isolation或在配置文件中设置:

[mysqld]transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}

2)服务启动后的设置:

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

事务属性ACID

1)原子性(Atomicity)

        所谓原子性就是将一组操作作为一个操作单元,是原子操作,即要么全部执行,要么全部不执行。

2)一致性(Consistency)

        事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

        只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。

3)隔离性(Isolation)

        隔离性指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被其它企图进行修改的事务看到

4)持久性(Durability)

        持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。即一旦一个事务提交,DBMS(Database Management System)保证它对数据库中数据的改变应该是永久性的,持久性通过数据库备份和恢复来保证。

 
原文地址:https://www.cnblogs.com/lsx1993/p/4619983.html