数据库事务的隔离级别(行锁还是表锁)

数据库事务的隔离级别,这个网上很多文章讲解,面试的时候也是经常问道,今天我从锁的角度再来理解一下这4个隔离级别,温故而知新。


SQL标准中定义了四种隔离级别:


一,未提交读(read uncommitted


未提交读(read uncommitted ):事务中的修改,即使没有提交,对其它事务也是可见的。事务可以读取未提交的数据,也称之为脏读。这个场景很容易理解,不再赘述。

加锁范围:不加锁

未提交读:什么都不保证。


二,已提交读(read committed )


已提交读(read committed ):只能读取到已经提交的数据,可以避免脏读。已提交读不能保证可重复读,也就是说,前后两次读取,会获取到不同的结果集。这里的不同结果集可能包含两种情况:

1,结果集行数不一致,insert和delete导致的。(幻读)

2,结果集中的某些记录不一致,update导致的。(不可重复读)


所以,大部分数据库的默认隔离级别都是这个级别:

MySQL的默认隔离级别:可重复读。

Oracle的默认隔离级别:已提交读。

DB2的默认隔离级别:已提交读。

加锁范围:行锁,只锁修改的行。比如我的update语句只修改一行记录,那么只锁这一行。

读已提交能够保证:我修改的10条数据,在我这个事务中,不会被其他事务改变。

读已提交不能保证:我读取的100条数据,在我这个事务中始终不变。



三,可重复读 (repeatable read)


可重复读 (repeatable read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。会出现幻读的情况,所谓的幻读,就是前后两次读取到的记录行数不一致。事务A在读取某些记录时,事务B又在事务A内插入了一条新记录,当事务A再次读取该范围的记录时,发现前后两次读取的结果集不是完全一致。

注意,这里有一个关键点:2次读取都是在同一个事务中!也就是说,可重复读指的是同一个事务中的读出来的数据是可以保证不被其他事务改变。

加锁范围:行锁,锁定所有查询的行。这里我个人理解是锁定返回结果集,也就是说我读取的这部分数据,其他事务是不能修改的。但是我再次读取的时候,结果集可能会发生变化。

可重复读能够保证:我读取的100条数据,在我这个事务中始终不变。

可重复读不能够保证:同一个查询语句,在同一个事务中,始终查询到100条记录。


四,串行读(Serializable)


串行读(Serializable):是最高的隔离级别,通过强制的事务串行执行,避免了前面说的幻读问题。简单的来说,Serializable会在读取的每张表上加锁,所以可能导致大量的超时和锁竞争的问题。实际应用中很少用到这一级别。

加锁范围:锁表。

你可能感兴趣的:(数据库事务的隔离级别(行锁还是表锁))