事务-隔离级别

来源:互联网 发布:摩卡相关软件 编辑:程序博客网 时间:2024/06/05 19:31

Read uncommitted
另一个事务可以看到这个事务未提交的数据
产生脏读,不可重复读和幻读。
set tx_isolation=’READ-UNCOMMITTED’;
select @@tx_isolation;
读取数据一致性在最低级别,只能保证不读物理上损坏的数据,会脏读,会不可重复读,会幻读。这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用。

Read committed
事务里面特定语句结束之后,不匹配该sql语句扫描条件的锁,会被释放。
一个事务修改的数据提交后才能被另外一个事务读取
(1)有一个交叉的事务有新的commit,导致了数据的改变;
(2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit
Oracle等多数数据库默认都是该级别
产生不可重复读
在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete)。
我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果
在本事务未提交之前其他已提交的事务的增删改操作提交后会影响读的结果。读的是最新结果。

读取数据一致性在语句级别,不会脏读,会不可重复读,会幻读。
仅能读取到已提交的记录,这种隔离级别下,会存在幻读现象,所谓幻读是指在同一个事务中,多次执行同一个查询,返回的记录不完全相同的现象。幻读产生的根本原因是,在RC隔离级别下,每条语句都会读取已提交事务的更新,若两次查询之间有其他事务提交,则会导致两次查询结果不一致。虽然如此,读提交隔离级别在生产环境中使用很广泛。

set tx_isolation=’read-committed’;
select @@tx_isolation;

Repeatable read
在读的过程中数据始终是事务启动时的数据状态,未提交之前其他事物的增删改操作提交后都不会影响读的结果。读的是快照结果。

读取数据一致性在事务级别,会幻读。
可重复读隔离级别解决了不可重复读的问题,但依然没有解决幻读的问题。不可重复读重点在修改,即读取过的数据,两次读的值不一样;而幻读则侧重于记录数目变化【插入和删除】。

set tx_isolation=’repeatable-read’;
select @@tx_isolation;
事务持有的 每个锁 在整个事务期间一直被持有
一个事务不能读取另一个事务未提交的数据
当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行
在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。
产生幻读

MySQL的默认事务隔离级别
同一事务的多个实例在并发读取数据时,会看到同样的数据行

InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题

InnoDB会为范围扫描创建间隙锁(gap locks):
select * from some_table where id > 100 FOR UPDATE;

上面的update将会创建一个 gap lock,用来防止在 id>100 范围内有新行被插入,锁会持续到事务回滚或提交。比如在同一个事务里,上午5点执行 SELECT … FOR UPDATE,下午5点执行 UPDATE some_table where id>100,那么这个update只会修改上午5点 SELECT FOR UPDATE所锁定的行,因为大于100的记录的整个 间隙 被加了锁

Serializable
顺序执行,在每个读的数据行上加上共享锁,导致大量的超时现象和锁竞争
set tx_isolation=’serializable’;
select @@tx_isolation;

读取数据一致性在最高级别,事务级别,但事务并发度急剧下降,事务的隔离级别与事务的并发度成反比,隔离级别越高,事务的并发度越低。实际生产环境下,dba会在并发和满足业务需求之间作权衡,选择合适的隔离级别。

原创粉丝点击