美文网首页
数据库隔离级别

数据库隔离级别

作者: 学编程的小屁孩 | 来源:发表于2020-03-19 10:08 被阅读0次

事务4个隔离界别

  • Read Uncommitted 最低的隔离级别,未提交读最直接的效果就是一个事务可以读取另一个事务并未提交的更新结果。

  • Read Committed 提交读是Oracle默认隔离级别,一个事务的更新操作结果只有在该事务提交之后,另一个事务才可能读取到同一笔数据更新后的结果。 可以避免未提交读隔离级别下存在的脏读问题, 无法避免不可重复读取和幻读的问题。

  • Repeatable Read 可重复度是mysql默认隔离级别,可以保证在整个事务的过程中,对同一笔数据的读取结果是相同的,不管其他事务是否同时在对同一笔数据进行更新,也不管其他事务对同一笔数据的更新提交与否。 Repeatable Read隔离级别避免了脏读和不可重复读取的问题,但无法避免幻读。

  • Serializable 串行读最为严格的隔离级别,所有的事务操作都必须依次顺序执行,可以避免其他隔离级别遇到的所有问题。是最为安全的隔离级别, 但同时也是性能最差的隔离级别。很少场景会使用它。通常情况下,我们会使用其他隔离级别加上相应的并发锁的机制来控制对数据的访问。

并发问题

脏读

(针对未提交数据)如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。

不可重复读

(针对其他提交前后,读取数据本身的对比)不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。

幻读

(针对其他提交前后,读取数据条数的对比) 幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。在Read Uncommitted隔离级别下, 不管事务2的插入操作是否提交,事务1在插入操作之前和之后执行相同的查询,取得的结果集是不同的,所以,Read Uncommitted同样无法避免幻读的问题。

不可重复读和幻读区别

对于不可重复读和幻读,可以借用下面的例子理解:

不可重复读

不可重复读的重点是修改:

同样的条件, 你读取过的数据, 再次读取出来发现值不一样了

例子:

在事务1中,Mary 读取了自己的工资为1000,操作并没有完成

con1 = getConnection();  
select salary from employee empId ="Mary";  

在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.

con2 = getConnection();  
update employee set salary = 2000;  
con2.commit();  

在事务1中,Mary 再次读取自己的工资时,工资变为了2000

 select salary from employee empId ="Mary";  

在一个事务中前后两次读取的结果并不致,导致了不可重复读。

幻读

幻读的重点在于新增或者删除 (数据条数变化),同样的条件, 第1次和第2次读出来的记录数不一样。

例子:

目前工资为1000的员工有10人。
事务1,读取所有工资为1000的员工。

con1 = getConnection();  
Select * from employee where salary =1000;  

共读取10条记录

这时另一个事务向employee表插入了一条员工记录,工资也为1000

con2 = getConnection();  
Insert into employee(empId,salary) values("Lili",1000);  
 con2.commit();  

事务1再次读取所有工资为1000的员工

select * from employee where salary =1000;  

共读取到了11条记录,这就像产生了幻读。

相关文章

网友评论

      本文标题:数据库隔离级别

      本文链接:https://www.haomeiwen.com/subject/luskyhtx.html