数据库有4层隔离级别,分别是read uncommited(读未提交),read commited(读提交),repeatable read(重复读),serializable(序列化)。
数据库隔离级别设置的主要原因是因为在高并发访问的情况下,我们需要知道那些数据是需要快速处理,并会出现安全问题,需要知道哪些数据是需要高并发处理不会出现安全问题。不同系统的安全级别是不同的,隔离级别越高,性能越低。
注意:更新是update操作,不包括insert,delete。
不同隔离级别会遇到不同的问题有脏读、不可重复度、幻读3中问题。
脏读:
事务A将数据Y修改为X但并未提交到数据库,这时事务B读到修改后的数据X,数据X就是脏数据,读取这些数据的动作就叫脏读,因为这些数据随时可能会被回滚,操作这些数据可能会出错。
不可重复读:
指一个事务范围内,两次读取的数据不一致。如事务A读取数据,事务B读取同一数据并更新数据,当A再次读取数据的时候,发现数据不一致。
幻读:
事务T1、T2,当事务T1读取数据,事务T2插入一行更新,事务T1再次读取数据的时候,发现多了一行,好像幻觉一样。幻读常用指代insert操作。
下面分别解释4中隔离级别。
1.read uncommited(隔离最低级别)
读未提交会造成脏读。该隔离级别下, 任何事务都可以看到某个事物修改的未提交的结果,该修改是可见的,这种隔离级别不满足所谓的隔离,没有起到隔离的效果,所以一般数据库默认的隔离级别都不是read uncommited。即事务A读取数据库数据,并修改改数据未提交,事务B可以看到该修改,读取这段数据,如果事物A需要回滚这段事务的话, 那么事务B读取的数据就是垃圾数据(脏数据)。读取未提交数据也成为脏读(Dirty Read)。
总结: 允许事务读取未被其他事务提交的变更,脏读、不可重复读和幻读的问题都会出现。
eg:财务部将小明这个月薪水6000元打入小明账户,小明看到非常高兴,这时候财务部发现打错了,应该是2000元,回滚事务,给小明工资改成2000,小明空欢喜一场。
2.read commited
读提交符合数据库的隔离的简单定义:当一个事务开始时到提交前,任何其他事务都看不到该事务所做的改变。
因为该隔离级别是读取的时候加锁,当读取完毕后,立马释放锁,全程加写锁。当事务A读取数据后,释放锁,事务B读取相同数据,这时候修改提交,A再次读的时候发现数据不同了,是不能重复读的。同理B插入一行提交,A再读一次发现多了数据。
总结: 只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然会出现 。
3.repeatable read
重复读确保了同一个事务的多个实例并发读取数据时,看到的是相同的数据。但是会出现幻读的问题,据即当前事务读取数,另外一个事务修改了数据,当前事务重新读取数据的时候发现不一样了,好像出现了幻觉一样。
总结: 确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,但是可以插入数据,可以避免脏读和不可重复读,但幻读的问题依然存在
4.serializable
隔离级别最高,按照顺序执行操作。
总结: 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可以避免,但性能十分低
总结:
数据的隔离级别越低,并发性越好,隔离级别越高,并发性越差