数据库是一个多线程的应用程序,多线程会存在并发的一些问题,这里主要针对幻读、不接重复读、脏读做一下介绍
脏读:一个事务读取到另一个事务未提交的数据
不可重复读:一个事务内多次查询显示的内容不一致
幻读:一个事务内多次查询的结果返回的条数不一致
数据库的事务是有隔离性的,隔离性有不同的实现,这里就引出事务的隔离级别,隔离级别的出现就是为了解决上面所提到问题。
事务的隔离级别分为:
- 读未提交(Read uncommitted):数据库中最低的事务隔离级别,可能有发生脏读、不可重复读、幻读
- 读已提交(Read Committed):事务之间只能读已经提交的,可以解决 脏读的问题,但不能解决 不可重复读、幻读问题
- 可重复读(Repeatable Reads):可以避免脏读、不可重复读,无法避免幻读
- 串行化(Serializable):可以理解为单线程执行,一个事务排队执行,可解决脏读,不可重复读,幻读问题
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | × | × | × |
读已提交(read-committed) | √ | × | × |
可重复读(repeatable-read) | √ | √ | × |
串行化(serializable) | √ | √ | √ |
Mysql都支持这四种隔离级别,默认的隔离级别为可重复读。
Oracle只支持:读已提交、串行化这两种隔离级别,默认的隔离级别为读已提交
注意:有的人可能有疑问,为什么会有这样的四种隔离级别,串行化不是已经解决了三种问题吗?虽然串行化解决了这三种问题,但是串行化的执行效率是非常低效的,里面有代码逻辑去控制使事务一个一个执行,这里使为了提高效率,比如mysql 的默认隔离级别为可重复读,因为幻读人们可以接受,换来了一个比较高的并发处理效率