Mysql数据库隔离级别
数据库事务四大特性(ACID)
原子性(Atomicity)
原子性是指事务中的操作要么全部成功,要么失败回滚。
一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
隔离性(Isolation)
隔离性是指两个事务之间的操作互不影响。关于事务的隔离级别后面将会介绍。
持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
隔离性会出现的问题
如果不采取数据库隔离会出现以下问题:
脏读
事务A将data的值由4修改成5,但是并未提交;此时事务B读取data的值是5.但是事务A并没有提交进行了回滚,此时事务B读取的就是一个脏数据(因为此时数据库中data的数据是4不是5)。
不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发生了不可重复读。不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了。
注:不可重复读强调的是多次查询,同样的select语句,但是2次读取的结果不一样。
幻读
幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
注:幻读的重点在于新增或删除:同样条件的select,读取的记录不一样。
数据库隔离级别
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
读未提交(read-uncommitted) | ✅ | ✅ | ✅ |
读提交(read-committed) | ❌ | ✅ | ✅ |
可重复读(repeatable-read) | ❌ | ❌ | ✅ |
串行化(Serializable) | ❌ | ❌ | ❌ |
- 串行化(Serializable)保证了完整的隔离性,是一致性最好,但是并发性最差的;
- 读未提交(read-uncommitted)一致性最差。
- 串行化、读未提交这两种在实际开发中基本不会用到。
- 可重复读(Repeatable-read):是MySQL默认的隔离级别。
- 通过“select @@tx_isolation”查看采用的隔离级别,通过"set tx_isolation=${isolation_level}"设置相应的隔离级别。