数据库四大事务隔离级别和三类数据读取现象
数据库的事务隔离级别是一个老生常谈的问题了。事务的四大隔离级别是指数据隔离的范围而言,具体是按照三类数据读现象(脏读、不可重复读、幻读)而来设置的。仍有不少人对不可重复读和幻读混淆。这里就再写一点。
数据库的事务四大隔离级别:
- 读未提交 Read uncommitted
- 读已提交 Read committed
Oracle、SQL Server的默认事务隔离级别都是读已提交。 - 可重复读 Repeatable read
MySQL默认的事务隔离级别 - 串行化读 Serializable
三类数据读现象:
-
脏读 Dirty Reads
脏读很容易理解,是指一个事务读取到了其它事务还没有提交的数据。例如,事务A更新了一行数据,事务B在事务A提交前读取到了这条更新后的数据。如果此时事务A回滚了事务,那么事务B读到的数据就是实际上不存在的,即脏数据。
读未提交(Read uncommitted)的事务隔离级别就是允许脏读,这是最低等级的数据隔离范围。 -
不可重复读 Non-repeatable Reads
不可重复读指的是一个事务前后两次读取同一批数据但是两次得到的数据不一样。例如,假设事务A读取一行数据,事务B更新或删除了这条数据并提交了事务;如果此时事务A重新读取这行数据,将得到被不一样的数据(被更新)或数据消失了(被删除)。
读已提交(Read committed)的事务隔离级别可以避免脏读的现象。但是无法避免不可重复读现象。 -
幻读 Phantoms
幻读容易和不可重复读混淆。幻读是指一行(或多行)符合查询条件的数据在第一次查询时没有出现,在第二次查询时却出现。例如,假设事务A执行一条查询语句,读取到一组(一行或多行)数据符合查询条件,随后事务B执行update或insert语句产生了新的一行(或多行)满足事务A查询条件的数据;此时如果事务A再执行一次同一条查询语句,但是这次得到查询结果数据行比上次的多了。
可重复读(Repeatable read)的事务隔离级别可以避免不可重复读现象,但是无法彻底避免幻读现象。
串行化读(Serializable)的事务隔离级别可以彻底避免这三类数据读现象,但是由于事务只能串行的执行,即上一个事务结束了(提交或回滚)之后才能执行下一个事务,会导致数据库的性能大大降低。
事务隔离级别规避的数据读现象的总结,打V的表示会出现,--的表示不会出现:
| 事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交(Read uncommitted) | V | V | V |
| 读已提交(Read committed) | -- | V | V |
| 可重复读(Repeatable read) | -- | -- | V |
| 串行化读(Serializable) | -- | -- | -- |
浙公网安备 33010602011771号