数据库事务以及脏读、幻读、不可重复读问题

数据库事务以及脏读、幻读、不可重复读问题,第1张

数据事务以及脏读、幻读、不可重复读问题 什么是事务?

  一组不可再分的数据库 *** 作序列

事务的作用?

  一组 *** 作数据库的执行语句,在设定合适隔离级别的条件下,控制一组数据库 *** 作的执行或回退。

事务的ACID特性?

1.原子性:事务的数据库 *** 作序列不可再分割,要么都执行,要么都不执行
2.一致性:在事务 *** 作前后,数据库中的数据必须保持一致性,非常常见的一组体现一致性的场景就是转账案例:在转账事务前后,最后的金钱总额是一致的,不能只转不增。
3.持久性:事务提交之后,对数据库的修改会持久化存储到数据库中,持久化的 *** 作不可逆转;
4.隔离性:事务之间应该互相独立,不会被其他事务干扰(理论上相互独立)

需要明白的是:隔离级别是为了解决在数据库并发访问下数据一致性的问题

事务的4种隔离级别:

1.read-unCommit 读未提交  

  这种隔离级别之下,并行事务执行过程中,事务之间读取数据可以读取到另一事务中还没提交的数据。

 容易造成脏读、不可重复读、幻读的错误。

脏读:事务第二次读取到的数据是错误的,与数据库中的存储的数据不一致。

          错误场景:A事务第一次读取数据之后,B事务对相同数据进行读取并更新数据,然后A事务第二次读取数据,读取到的是B事务更新之后的数据,然后B事务进行了回滚 *** 作,此时数据库中的数据还是未更新之前的数据,但是A事务第二次读取到的数据是B事务更新后的数据,读取的数据与数据库中的数据不一致。这就是脏读。

解决方式:提高隔离级别为read-Commit 读已提交

2. read-Commit 读已提交

     这种隔离级别下,并行事务执行过程中,读取到的数据是并行事务提交之后的变化数据。

   解决脏读,出现不可重复读、幻读问题;

  读已提交的隔离级别下解决脏读的方式:使用共享锁(读取数据时,其他事务不能再对数据进行更改,只能读取,读取之后就会释放锁)、排他锁(更新数据时,其他事务不能再对更改数据进行读取和写,事务提交后释放锁)。

    解决方式:A事务读取数据加上共享锁,B事务对相同数据读取并更新数据,对该数据加上排他锁,在B事务提交之前,更新后的数据不能被读写,此时A事务再查询数据,就是之前未更改的数据。在B事务提交之后就可以释放排他锁,之后事务A读取数据,就是正确的更新之后的数据,即使事务B回滚,事务A每次读取的数据也是正确的数据。  

   引发新的问题:在B事务提交之后的情况中,A事务读取的数据不一样的,在同一事务中两次读取的数据是不一致的,这就造成了不可重复读的问题 

  解决方式:提高隔离级别

3.可重复读:

  解决 不可重复读问题

  解决方式:延长共享锁的释放时机(在事务提交之后才将共享锁放开)

  事务A读取数据时加上共享锁,在A事务提交,将共享锁释放之前。其他事务无法对数据读取和更改,事务B读取并修改同一数据的 *** 作自动阻塞,此时A事务读取相同的数据,还是第一次读取的数据,解决了不可重复读的问题。

  还存在新的问题:事务A在读取数据后,事务B对相同条件的数据结果中insert了新的数据,事务A在读取新的数据之后,发现记录数发生了变化,和之前的记录数不一样,好像发生了幻觉,这就是新的问题----幻读。

解决方式:提高隔离级别

4.串行化(最高隔离级别,安全但效率最低)

解决幻读:添加范围锁

   每一个事务都好像加上了锁,独立执行。安全性极高,效率很低


 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5682155.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存