MySql脏读幻读不可重复读

什么是数据库事务,为啥要有?

        事务:由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个整体不可分割

        假如A转账给B 100 元,先从A的账户里扣除 100 元,再在 B 的账户上加上 100 元。如果扣完A的100元后,还没来得及给B加上,银行系统异常了,最后导致A的余额减少了,B的余额却没有增加。所以就需要事务,将A的钱回滚回去,就是这么简单。

        为啥要有?保证数据的最终一致性

事务的特性

        四个典型特征:原子性,一致性,隔离性,持久性

        原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部执行,要么都不执行。

        一致性:几个并行执行的事务,其执行结果必须与按某一顺序 串行执行的结果相一致。假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。

        隔离性:事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务透明。

        持久性:事务完成提交后,事务对数据库所作操作更改,持久保存在数据库中

1.脏读(dirty read)

        原因:

        指事务读取到其他事务未提交的值

        例子:事务A/B和一条记录:id=1,name=王五

        A修改id=1中的name值为李四,但是还为提交事务

        B再A事务未提交时进行查询,查询出来的结果是id=1的数据库中,name的值为李四

        然后重点来了

        A回滚修改的name的值,现在数据库存的王五,但是B查询出来的却是李四;

        这就是脏读,事务B读取了事务A未提交的数据

2.不可重复读(non-repeatable read)

        原因:

        不可重复读是指再同一次事务中前后查询不一致

        例子:事务A查询一条记录,name=王五,事务B执行更新name=李四,并且提交了,A按照相同的条件查询,name=李四,事务A就会出现一个问题,同样查询的语句,两次执行结果不一致

        同一事物前后查询不一致

3.幻读(phantom read)

        原因:

        并发事务的存在导致的。当多个事务同时执行相同查询操作时,如果其中有一个事务进行了插入、更新或删除操作,有可能导致其他事务的查询结果不同

        例子:事务A先执行查询,只有一条数据,事务B插入一条数据,A按照相同条件查询,结果多了一条记录

4. 总结

        脏读是指事务读取到其他事务正在处理的未提交数据

        不可重复读指在并发更新时,另一个事务前后执行相同条件的查询得到的数据不一致

        幻读指并发插入、删除时,另一个事务前后执行相同条件的查询得到的数据不一致

5.解决办法

        如何解决以上问题,事务的隔离级别就派上用场了

        禁止写时读,避免了“脏读”,对应隔离级别read committed。

        禁止读时写,避免了“不可重复读”,对应隔离级别repeatable read。

        而为了避免“幻读”,干脆把整个表给锁住了,只能是serialize了。

        隔离级别越高,并行度越低,付出的代价越大。

        MySQL默认事务隔离级别为:可重复读(repeatable-read),因此当我们使用MySQL进行实际开发时一般不会发生“脏读”和“不可重复读”。现在可能遇到的问题就是“幻读”,不过MySQL通过多版本并发控制(MVCC)机制解决了该问题。

6、事务的隔离界别(补充)

        读未提交(Read Uncommitted):读的是另一个事务未提交的数据,导致脏读、不可重复读、幻读

        读已提交(Read Committed):读取已经提交的数据,还是会造成幻读,不可重复读

        可重复读(Repeatable Read): 确保一个事务在多次读取同一数据时,能看到同样的数据行,可以避免脏读和不可重复读,但依旧可能存在幻读

        串行化(Serializable): 最高的隔离级别,避免所有的并发问题,但是会降低并发性能

7.数据库是如何保证事务的隔离性的

        加锁:例如,你晚上想在屋里安静的刷剧,给房门加把锁,别让别人进来足以

        串行化隔离级别就是枷锁实现的,频繁的加锁会降低数据库性能

        解决加锁后的性能问题就要了解mvcc多版本并发控制(再写啦)了

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值