MySQL 事务(详细版)

[复制链接]
发表于 2025-9-22 00:25:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
一、事务简介
1、事务的概念        
2、事务实行的案例
3、对于事务的明白
二、事务操纵
(一)未控制事务
(二)控制事务一
(三)控制事务二
三、事务四大特性
四、并发事务问题
五、事务隔离级别
1、事务隔离级别的介绍        
2、操纵事务隔离级别的语法
3、实例分析(串行化)

一、事务简介

1、事务的概念       

        事务是一组操纵的聚集,它是一个不可分割的工作单元。
        当我们进行事务操纵时,事务会把全部的操纵作为一个团体一起向体系提交或打消操纵哀求,即这些操纵要么同时乐成,要么同时失败。
2、事务实行的案例

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

        正常情况:转账这个操纵,需要分为以下这么三步来完成,三步完成之后,张三淘汰1000,而李四增长1000,转账乐成。

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

        为了办理上述的问题,就需要通过数据的事务来完成。
        我们只需要在业务逻辑实行之前开启事务,实行完毕后提交事务。如果实行过程中报错,则回滚事务,把数据规复到事务开始之前的状态。
3、对于事务的明白

        默认情况下,每一条SQL语句都是一个事务。这条SQL语句一旦实行完成,事务就会自动提交,也就是说,当实行完一条DML语句时,MySQL会立即隐式的提交事务。
        事务一旦提交,表格就会有对应的变革。
        如果有一件事,比方上面的转账操纵,必须三个步调同时完成才可以,此时就需要将几条SQL语句作为一个事务,包管它们同时乐成或同时失败不影响原来的数据。
        所以此时我们就要对事务进行控制,将几条SQL语句组合为一个事务。如果乐成,就同一提交,如果失败,则制止影响数据库的内容。
二、事务操纵

数据准备:
  1. drop table if exists account;
  2. create table account(
  3.     id int primary key AUTO_INCREMENT comment 'ID',
  4.     name varchar(10) comment '姓名',
  5.     money double(10,2) comment '余额'
  6. ) comment '账户表';
  7. insert into account(name, money) VALUES ('张三',2000), ('李四',2000);
复制代码


(一)未控制事务

1、测试正常情况
  1. -- 1. 查询张三余额
  2. select * from account where name = '张三';
  3. -- 2. 张三的余额减少1000
  4. update account set money = money - 1000 where name = '张三';
  5. -- 3. 李四的余额增加1000
  6. update account set money = money + 1000 where name = '李四';
复制代码
        测试完毕之后检查数据的状态,可以看到数据操纵前后是一致的。(总余额)

2、测试非常情况
  1. -- 1. 查询张三余额
  2. select * from account where name = '张三';
  3. -- 2. 张三的余额减少1000
  4. update account set money = money - 1000 where name = '张三';
  5. -- SQL语句中写中文必然报错
  6. -- 但是在dataship中这条语句会被跳过,实际执行时,不会报错
  7. 出错了....
  8. -- 3. 李四的余额增加1000
  9. 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 ;
  1. -- 开启事务start transaction -- 1. 查询张三余额
  2. select * from account where name = '张三';
  3. -- 2. 张三的余额减少1000
  4. update account set money = money - 1000 where name = '张三';
  5. -- 3. 李四的余额增加1000
  6. 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 事务的全部内容,创作不易,麻烦三连支持一下呗~  

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表