• MySQL事务详解


    目录

    引例

    什么是事务

    一个完整事务所具有的四大属性

    为什么会出现事务

    事务常见操作方式

    事务隔离级别

    为什么要存在隔离级别

    一致性


    引例

    如下图,是一个火车售票系统,当客户端A发现还有一张票时,将票卖掉,还没执行更新数据库

    时,客户端B发现票数大于0,又卖了一次票,A将票数更新回数据库,这样就出现了同一张票卖出

    去两次的情况

    CURD得满足下面4个特性,才能解决上述问题

    买票的过程得是原子的吧
    买票互相应该不能影响吧
    买完票应该要永久有效吧
    买前,和买后都要是确定的状态吧

    什么是事务

    假设一种场景:你毕业了,学校的教务系统后台 MySQL 中,不再需要你的数据,要删除你的所有
    信息(一般不会),那么在删除你的基本信息(姓名,电话,籍贯等)的同时,也删除和你有关的其他
    信息,比如:你的各科成绩,你在校表现,甚至你在论坛发过的文章等。这样,就需要多条
    MySQL 语句构成,那么所有这些操作合起来,就构成了一个事务
    所有的sql操作,一般都会被mysql包装成为事务,以事务的方式提交的!!!

     一个完整事务所具有的四大属性(简称:ACID)

    原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在 中 间某个环节。事
    务在执行过程中发生错误,会被回滚到事务开始前的状态,就像 这个 事务从来 没有执行过一样
    一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完
    全符合所有 的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工
    作
    隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务
    并发执行时 由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交 、读提交 、
    可重复读和串行化
    持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失
    为什么会出现事务
    为了当应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要我们去考虑各种各
    样的潜在错误和并发问题,本质上是为了应用层服务的
    MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持,如下图
    事务的提交方式常见的有两种:
    自动提交
    手动提交
    自动提交默认是打开的!
    也能自己打开或关闭!
    事务常见操作方式
    为了便于演示,我们将mysql的默认隔离级别设置成读未提交
    设置后需要重启终端,进行查看

    正常演示 - 证明事务的开始与回滚
    启动事务:start transaction / begin
    savepoint s:在两条记录间设置断点
    rollback to s:回滚到断点s前的上一条数据(s是在两条记录间设置的断点)
    rollback:回滚到最开始
    非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚
    手动启动一个事务的时候,和mysql中是否事务会自动提交无关!如下图
    非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会再受影响,已经持久化
    非正常演示3 - 证明单条 SQL 与事务的关系
    事务没有启动,自动提交打开与不打开的区别如下图

    其实我们之前的所有的单条sql,本质在mysql中,全部各自会被以事务的方式进行提交!

    自动提交是给mysql中的单挑sql设置的,即我们的默认行为

    注意:如果一个事务被提交了,则不可以回退!!!

    事务隔离级别

    一个事务可能由多条SQL构成,也就意味着,任何一个事务,都有执行前,执行中,执行后的阶段
    数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性 
    数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别
    隔离级别
    读未提交(Read Uncommitted): 在该隔离级别,所有的事务都可以看到其他事务没有提交的
    执行结果,相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等
    读提交(Read Committed) :该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认
    的),它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变,会引起不
    可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果
    可重复读(Repeatable Read): 这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多
    次读取操作数据时,会看到同样的数据行,会有幻读问题
    串行化(Serializable): 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,
    从而解决了幻读的问题,在每个读的数据行上面加上共享锁,但是可能会导致超时和锁竞争
    隔离级别如何实现:隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。常见
    有,表锁,行锁,读锁,写锁,间隙锁(GAP),Next-Key锁(GAP+行锁)等
    查看与设置隔离性(不同版本,查看方式可能不同)
    SELECT @@global.tx_isolation(全局) / session.tx_isolation(当前会话) / tx_isolation;
    SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED |
    READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
    设置当前会话隔离性,只影响当前会话,不需要重启
    设置全局隔离性,另一个会话也会被影响,需要重启
    读未提交
    如下图,一个事务插入数据未提交,就能被另一个事务读取到,这种现象叫做脏读!如果是误操
    作,然后将读取后的结 果交 给上层,就会很不安全!
    读提交
    如下图,左端事务提交前和提交后,右端事务读取到两种结果,这种现象叫做不可重复读,不可重
    复读是一个问题
    你已提交,别人能读到,不应该等价于,你已经提交,和你"并行运行"的事务也能读到!!!
    不可重复读有什么问题——应用层会有什么影响?以银行为例
    如下图,王某在银行的钱余额因为个人原因存在一些变化,从10亿->5500w->3000w,而银行读取
    事务这边就会因为不可重复读,即每次读到的值不一样,给王某发了三个礼物,这是存在很大的安
    全问题的!!!
    可重复读
    如下图,左端事务修改完毕提交后,右边事务读取的值还是未发生改变,只有右边事务也commit
    后,才能看到更新后的数据!这种现象叫做可重复读!
    一般的数据库在可重复读情况的时候,无法屏蔽其他事务insert的数据,因为隔离性实现是对数据
    加锁完成的,而insert待插入的数据因为并不存在,那么一般加锁无法屏蔽这类问题,会造成虽然
    大部分内容是可重复读的,但是insert的数据在可重复读情况被读取出来,导致多次查找时,会多
    查找出来新的记录,就如同产生了幻觉。这种现象,叫做幻读,MySQL解决了这个问题!
    串行化
    如下图,左端事务更新数据,却卡住了,只能等右端提交后,更新语句才能结束,这说明串行化指
    的是事务之间的串行

    隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平衡

    点!!!

    隔离性:mysql的内部机制,让"同时"启动,并发执行的各个事务,看到不同的数据修改(增删

    改),就叫做隔离性!

    隔离级别:我们作为一个事务,可以看到不同可见性的数据,程度的不同,叫做隔离级别!

    为什么要存在隔离级别

    为了安全和效率,安全和效率之间需要找平衡点,这不是mysql决定的,而是由用户决定的,而至

    于为什么有种类繁多的隔离级别,这是因为应用场景的需要,比如某些场景下,不需要考虑安全,

    只注重效率就行!

    一致性

    事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态
    MySQL中在技术上不存在一致性,技术上,是通过AID(原子性,持久性,隔离性)保证C(一致性)
    例如:你给别人转账,你账上的余额减少了,而对方的余额因为系统运行中断却没有增加,这就没
    有保证原子性! 你在买票APP上买了一张票,但是当 你去坐车的时候,工作人员告诉你,没有你的
    信息,即磁盘上没有保存你的信息,这就可能会给你 带来很 大的损失,这就没有保证持久性!王某
    的帐上余额的变化,不可重复读,使得银行多次来人拜访他,打扰了他的生活,就让他很苦恼,这
    就没有保证隔 离性!这三例都表明了原子性,持久性,隔离性都是为实现一致性服务的!!!
    一致性:由用户和MySQL共同决定!!!
  • 相关阅读:
    基于SpringBoot的SSMP整合案例
    Docker和Docker compose的安装使用指南
    基于Pytorch框架的轻量级卷积神经网络垃圾分类识别系统
    Luxury Hotelschool Paris加大投资力度,为奢华酒店行业的未来培养人才
    c++可视化性能测试
    element-UI 列表渲染图片,后台回传Base64
    java spring cloud 企业工程管理系统源码+二次开发+定制化服务
    将设计模式门面模式运用到生活当中
    RabbitMQ 简介
    Spire.Office for Java 8.9.7 Crack
  • 原文地址:https://blog.csdn.net/weixin_58867976/article/details/128040619