当前位置: 首页 > news >正文

MySQL 事务(详细版)

目录

一、事务简介

1、事务的概念        

2、事务执行的案例

3、对于事务的理解

二、事务操作

(一)未控制事务

(二)控制事务一

(三)控制事务二

三、事务四大特性

四、并发事务问题

五、事务隔离级别

1、事务隔离级别的介绍        

2、操作事务隔离级别的语法

3、实例分析(串行化)


一、事务简介

1、事务的概念        

        事务是一组操作的集合它是一个不可分割的工作单位。

        当我们进行事务操作时,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

2、事务执行的案例

        就比如:张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加 1000。 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。

        正常情况:转账这个操作,需要分为以下这么三步来完成,三步完成之后,张三减少1000,而李四增加1000,转账成功。

        异常情况:转账这个操作,也是分为以下这么三步来完成,在执行第三步是报错了,这样就导致张三减少1000块钱,而李四的金额没变,这样就造成了数据的不一致,就出现问题了。

        为了解决上述的问题,就需要通过数据的事务来完成。

        我们只需要在业务逻辑执行之前开启事务,执行完毕后提交事务。如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态。

3、对于事务的理解

        默认情况下,每一条SQL语句都是一个事务。这条SQL语句一旦执行完成,事务就会自动提交,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务。

        事务一旦提交,表格就会有对应的变化。

        如果有一件事,例如上面的转账操作,必须三个步骤同时完成才可以,此时就需要将几条SQL语句作为一个事务,保证它们同时成功或同时失败不影响原来的数据。

        所以此时我们就要对事务进行控制,将几条SQL语句组合为一个事务。如果成功,就统一提交,如果失败,则避免影响数据库的内容。

二、事务操作

数据准备:

drop table if exists account;create table account(id int primary key AUTO_INCREMENT comment 'ID',name varchar(10) comment '姓名',money double(10,2) comment '余额'
) comment '账户表';
insert into account(name, money) VALUES ('张三',2000), ('李四',2000);
(一)未控制事务

1、测试正常情况

-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';

        测试完毕之后检查数据的状态,可以看到数据操作前后是一致的。(总余额)

2、测试异常情况

-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
-- SQL语句中写中文必然报错
-- 但是在dataship中这条语句会被跳过,实际执行时,不会报错
出错了....
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';

        我们把数据都恢复到2000, 然后再次一次性执行上述的SQL语句(出错了.... 这句话不符合SQL语法,执行就会报错),检查最终的数据情况,发现数据在操作前后不一致了(总余额)

(二)控制事务一

1、查看/设置事务提交方式

-- 查看事务的提交方式

select @@autocommit ;

-- 如果赋值为1,就是自动提交事务;

-- 如果赋值为0,就是手动提交事务;

-- MySQL中默认自动提交事务,所以要设置为手动。

set @@autocommit = 0 ;

2、提交事务

-- 手动提交的情况下,要执行了commit,事务才会提交,数据库中内容才会发生改变。

commit ;

3、回滚事务

-- 执行过程中,如果发生了异常,就去执行rollback回滚,撤回该事务内已执行的操作。

rollback ;

注意事项:

        上述的这种方式,我们是修改了事务的自动提交行为,把默认的自动提交修改为了手动提
,此时我们执行的DML语句都不会提交,需要手动的执行commit进行提交

        如果业务操作正常完成,事务需要提交,就执行commit指令;如果执行事务操作的过程中出现了异常,那就执行rollback指令回滚事务,保证数据库中数据的正确性与完整性

(三)控制事务二

1、开启事务

-- 手动开启事务,而不是修改事务的提交方式

start transaction ; 或 begin ;

2、提交事务

-- 如果事务执行成功,执行commit指令

commit ;

3、回滚事务

-- 如果事务执行失败,执行rollbakc指令

rollback ;

-- 开启事务
start transaction -- 1. 查询张三余额
select * from account where name = '张三';-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';-- 如果正常执行完毕, 则提交事务
commit;-- 如果执行过程中报错, 则回滚事务
-- 回滚事务之后就代表着当前事务已经结束了
rollback;

三、事务四大特性

1、原子性(Atomicity)

        事务是不可分割的最小操作单元,要么全部成功,要么全部失败。

2、一致性(Consistency)

        事务完成时,必须使所有的数据都保持一致状态。

3、隔离性(Isolation)

        数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

        就如下图的上半部分,事务AB并发执行,但是不会相互影响。事务A在操作的时候,不会影响并发的事务B的执行;事务B在操作的时候,也不会影响并发的事务A的执行;它们两个是在独立的环境下运行的。

4、持久性(Durability)

        事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

        就如下图的下半部分,因为数据库当中的数据最后是存储在了磁盘当中的,而存储在磁盘当中的数据,就可以永久地保留下来。

四、并发事务问题

        并发事务问题是事务A和事务B在同时操作某一个数据库甚至一张表时,引发的问题。

1、赃读:一个事务读到另外一个事务还没有提交的数据

        比如,在事务A执行了 select 与 update 语句后,并未提交;但是在事务B中执行 select 语句后,却查询到了事务A未提交的数据。

2、不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读

        比如,在事务A两次读取同一条记录,却因为期间事务B中 id=1 的数据被更新且提交导致读取到的数据却是不一样的。

3、幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了 "幻影"。

        比如,在事务A中第一次查询,没有查询到信息;然后事务B中插入并提交了id =1的数据;此时在事务A中插入 id = 1 的数据无法插入,因为 id 是主键,id =1的数据在事务B中就已经插入;但是在事务A中再查询一次后,又无法查询得到。

五、事务隔离级别

1、事务隔离级别的介绍        

        为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下几种

        Repeatable Read是MySQL的默认事务隔离级别

        事务隔离级别越高,数据越安全,但是性能越低;反之事务隔离级别越低,性能越高,但是数据越不安全。所以我们要权衡数据的安全性以及数据库的并发性能。

        其中,串行化指的是再进行并发事务操作的时候,一次只允许操作一个事务

        事务A在操作的时候,只有当事务A提交完成之后,事务B才能来操作。

        就比如上面幻读的例子中,如果是在串行化的情况下,因为事务A是在事务B之前执行,所以事务A执行完成之前,事务B根本无法执行下去。

        事务B执行insert语句在执行后,光标会一直卡着,直到事务A执行完毕后,事务B才会执行,这样就可以避免幻读。

2、操作事务隔离级别的语法

(1)查看事务隔离级别

select @@transaction_isolation

(2)设置事务隔离级别

-- session与global二选一

-- session 是指当前设置的事务隔离级别 仅对当前对话窗口有效

-- global 是指当前设置的事务隔离级别 对所有对话窗口有效

-- 后面的四个事务隔离级别四选一即可

set { session | global } transaction isolation level { Read Uncommitted | Read committed | Repeatable Read | Serializable}

3、实例分析(串行化)

        通过cmd打开两个命令行,在里面执行SQL语句,模拟两个并发事务。在下图中上面的命令行为事务A,下面的命令行为事务B。

(1)事务A还没有提交之前

        事务隔离级别为Serializable (串行化) 时,一次只允许操作一个事务,所以即便事务B的insert语句被执行了,光标也会一直卡着,无法执行,直到事务A执行完毕。

(2)事务A提交之后

        事务A提交后,事务B即可执行,但是此时 id = 3 的数据已经存在, 所以会报错

         
        以上即为MySQL 事务的全部内容,创作不易,麻烦三连支持一下呗~  

相关文章:

  • 2025五一杯数学建模竞赛思路助攻预定
  • 【Java面试笔记:进阶】18.什么情况下Java程序会产生死锁?如何定位、修复?
  • java多线程(3.0)
  • 【25软考网工】第三章(3)虚拟局域网VLAN
  • 拆解华为Pura X新发现:“仿生”散热与钛合金“骨架”
  • 每日算法——快乐数、两数之和
  • C++学习:六个月从基础到就业——STL算法(二)排序与变序算法
  • 《AI大模型应知应会100篇》 第36篇:RAG技术入门:检索增强生成原理及实现
  • 施磊老师基于muduo网络库的集群聊天服务器(六)
  • mybatis log convert使用
  • Java 高频面试题解析
  • 【android bluetooth 协议分析 06】【l2cap详解 9】【L2cap通道生命周期】
  • 【MobaXterm】---修改 MobaXterm 终端 默认字体和大小 保真
  • QSPI flash xip模式运行
  • 四、Python编程基础04
  • 《宝可梦明耀之星》正式登陆中国大陆!4月15日起陆续上市!
  • 母婴店商城小程序制作哪家强?告别传统经营,拥抱线上新机遇
  • TypeScript 开发实战:如何安全替换字符串中的关键字
  • 阿里云99机器总是宕机,实测还是磁盘性能差
  • 多路转接epoll原理详解
  • 技术派|“会飞的手榴弹”:微型无人机将深刻改变单兵作战方式
  • 李良生已任应急管理部党委委员、政治部主任
  • 专家解读上海一季度经济数据:经济韧性在增强,民企活力不可小觑
  • 重庆一幼儿园回应招聘硕士幼教:统一标准,江北区学前教育岗的硬性要求
  • 电影“名场面”被制成表情包在网站上传播,网站运营者被判赔5500元
  • 耐克领跑女性运动市场:持续加码、创新,更多新增长点有望涌现