MySQL(一)---事务

MySQL事务

#1 事务

事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。

#2 事务特性

一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  • 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

#3 MySQL隔离

#3.1 为什么需要设置隔离?

在数据库操作中,在并发的情况下可能出现如下问题

  • 更新丢失(Lost update)
  • 脏读(Dirty Reads)
  • 不可重复读(Non-repeatable Reads)
  • 幻象读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ctJR8NqQ-1583433950250)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200303161559-image.png)]

#3.1.1 更新丢失(Lost update)

当两个事务选择同一行,然后更新数据,由于每个事务都不知道其他事务的存在,就会发生丢失更新的问题,(你我同时读取同一行数据,进行修改,你commit之后我也commit,那么我的结果将会覆盖掉你的结果)

事务A覆盖事务B已经提交的数据,造成事务B所做的操作丢失。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HXQ91e6L-1583433950252)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200226164822-image.png)]

解决方法:对行加锁,只允许并发一个更新事务。

#3.1.2 脏读(Dirty Reads)

一个事务正在对一条记录做修改,在这个事务提交之前,别的事务读取到了这个事务修改之后的数据,也就是说,一个事务读取到了其他事务还没有提交的数据,就叫做脏读。

20200226165330-image.png

解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可以避免该问题。

#3.1.3 不可重复读(Non-repeatable Reads)

不可重复读 就是一个事务读到另一个事务修改后并提交的数据(update)。在同一个事务中,对于同一组数据读取到的结果不一致。比如,事务B 在 事务A 提交前读到的结果,和在 事务A 提交后读到的结果可能不同。不可重复读出现的原因就是由于事务并发修改记录而导致的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QnnODucG-1583433950254)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200226165445-image.png)]

解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

#3.1.4 幻象读

一个事务中,读取到了其他事务新增的数据,仿佛出现了幻象。(幻读与不可重复读类似,不可重复读是读到了其他事务update/delete的结果,幻读是读到了其他事务insert的结果)。例如:目前工资为1000的员工有10人。那么事务1中读取所有工资为1000的员工,得到了10条记录;这时事务2向员工表插入了一条员工记录,工资也为1000;那么事务1再次读取所有工资为1000的员工共读取到了11条记录。

20200226165834-image.png

解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题

#3.2 MySQL隔离级别?

数据库事务的隔离级别有4个,由低到高依次为:

  • Read uncommitted(未授权读取、读未提交)
  • Read committed(授权读取、读提交)
  • Repeatable read(可重复读取)
  • Serializable(序列化)

这四个级别可以逐个解决脏读、不可重复读、幻象读这几类问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TItO3Trj-1583433950263)(https://raw.githubusercontent.com/Coxhuang/yosoro/master/20200303165736-image.png)]

#3.2.1 Read uncommitted(未授权读取、读未提交)

就是一个事务可以读取另一个未提交事务的数据。最低级别,它存在4个常见问题(脏读、不可重复读、幻读、丢失更新)。

#3.2.2 Read committed(授权读取、读提交)

就是一个事务要等另一个事务提交后才能读取数据。 它解决了脏读问题,存在3个常见问题(不可重复读、幻读、丢失更新)。

#3.2.3 Repeatable read(可重复读取)

MySQL默认隔离级别,在一个事务中,直到事务结束前,都可以反复读取到事务刚开始时看到的数据,并一直不会发生变化,避免了脏读、不可重复读现象,但是它还是无法解决幻读问题。 。它解决了脏读和不可重复读,还存在2个常见问题(幻读、丢失更新)。

#3.2.4 Serializable(序列化)

序列化,或串行化。就是将每个事务按一定的顺序去执行,它将隔离问题全部解决,但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值