MySql事务及事务隔离级别实例与演示

本专栏将从基础开始,循序渐进,讲解数据库的基本概念以及使用,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址: 数据库必知必会
相关软件地址:软件地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。

环境的准备

-- 账户表
create table account(
    id int primary key auto_increment,
    name varchar(20),
    money double
);

insert into account values (null,'zs',1000);
insert into account values (null,'ls',1000);
insert into account values (null,'ww',1000);

事务的概述

目标

  • 掌握什么是事务以及事务作用

什么是事务

  • 事务指逻辑上的一组操作,组成这组操作的单元要么全部成功,要么全部失败。
    • 操作: zs向李四转账100元
    • 组成单元: zs钱-100, ls钱+100
      • 操作成功: zs钱900,ls钱1100
      • 操作失败: zs钱1000,ls钱1000
      • 不可能发生: zs钱900,ls钱1000; zs钱1000,ls钱1100

事务的作用

​ 保证一组操作全部成功或者失败。

小结

  1. 事务是逻辑上的一组操作, 组成这组操作的单元要么全部成功, 要么全部失败
  2. 作用: 保证全部成功或者全部失败

MYSQL进行事务管理

目标

  • 掌握MYSQL进行事务管理

自动事务(mysql默认)

​ 一条sql语句就是一个事务

-- 场景: zs向ls转账100元
-- zs钱-100 ls钱+100
-- 自动事务管理: MySQL默认就是自动事务管理(自动开启事务,自动提交事务),一条sql语句就是一个事务
update account set money = money - 100 where name = 'zs';
-- 异常
update account set money = money + 100 where name = 'ls';

手动开启一个事务

  • 方式一: 手动开启事务的方式 【掌握】

    ​ start transaction;开启事务

    ​ commit;提交

    ​ rollback;回滚

    -- 没有异常
    start transaction; -- 开启事务
    update account set money = money - 100 where name = 'zs'; -- zs钱-100
    -- 没有异常
    update account set money = money + 100 where name = 'ls'; -- ls钱 +100
    commit; -- 提交事务
    
    
    -- 有异常
    start transaction; -- 开启事务
    update account set money = money - 100 where name = 'zs'; -- zs钱-100
    -- 有异常
    update account set money = money + 100 where name = 'ls'; -- ls钱 +100
    rollback; -- 回滚事务
    
    

image-20200930123159442

  • 方式二: 设置MYSQL中的自动提交的参数

    查看MYSQL中事务是否自动提交

    show variables like '%commit%';
    

    设置自动提交的参数为OFF

    set autocommit = 0;-- 0:OFF  1:ON
    

回滚点

什么是回滚点

​ 在某些成功的操作完成之后,后续的操作有可能成功有可能失败,但是不管成功还是失败,前面操作都已经成功,可以在当前成功的位置设置一个回滚点。可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称之为回滚点。

回滚点的操作语句

img

具体操作

  1. 将数据还原到1000

  2. 开启事务

  3. 让张三账号减3次钱

  4. 设置回滚点:savepoint three_times;

  5. 让张三账号减4次钱

  6. 回到回滚点:rollback to three_times;

  • 总结:设置回滚点可以让我们在失败的时候回到回滚点,而不是回到事务开启的时候。
start transaction;
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
-- 以上sql语句没有问题
savepoint abc;
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
-- 出现异常,回滚到abc回滚点位置
rollback to abc;
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
update account set money = money - 100 where name = 'zs'; -- zs账户-100
commit;

应用场景

插入大量的数据的时候.  1亿条数据 需要插入很久.  要求: 1亿条数据是一个整体,要么全部插入成功的 要么都不插入成功.

小结

  1. 手动开启事务 语法

    start transaction;  -- 开启事务
    commit;             -- 提交
    rollback;           -- 回滚
    
  2. 注意

    • 建议手动开启事务, 用一次 就开启一次
    • 开启事务之后, 要么commit, 要么rollback
    • 一旦commit或者rollback, 当前的事务就结束了
    • 回滚到指定的回滚点, 但是这个时候事务没有结束的

事务特性和隔离级别

目标

  • 掌握事务的特性和隔离级别

事务特性

  • 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

    eg: zs 1000; ls 1000; 
    	zs 给 ls转100
    	要么都发生zs 900; ls 1100;
    	要么都不发生zs 1000; ls 1000;
    
  • 一致性(Consistency)事务前后数据的完整性必须保持一致.

    eg: zs 1000; ls 1000;  一共2000
    	zs 给 ls转100
    	要么都发生zs 900; ls 1100; 	一共2000
    	要么都不发生zs 1000; ls 1000; 一共2000
    
  • 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

    eg: zs 1000 给小红 转520, 张三 提交了
    
  • 隔离性(Isolation)事务的隔离性是指多个用户并发操作数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。 简单来说: 事务之间互不干扰

如果不考虑隔离性,会引发下面的问题

​ 事务在操作时的理想状态: 所有的事务之间保持隔离,互不影响。因为并发操作,多个用户同时访问同一个数据。可能引发并发访问的问题

img

事务隔离级别

​ 可以通过设置事物隔离级别解决读的问题

事务四个隔离级别

级别 名字 隔离级别 脏读 不可重复读 幻读 数据库默认隔离级别
1 读未提交 read uncommitted
2 读已提交 read committed Oracle
3 可重复读 repeatable read MySQL
4 串行化 serializable

隔离级别越高,安全性越高,性能(效率)越差。

设置隔离级别

  • 设置事务隔离级别
set session transaction isolation level  隔离级别;
eg: 设置事务隔离级别为:read uncommitted,read committed,repeatable read,serializable
set session transaction isolation level read uncommitted;
  • 查询当前事务隔离级别
select @@tx_isolation;

小结

  1. 事务的特性(今天需要理解, 面试之前背诵一下.)
    • 原子性
    • 一致性
    • 持久性
    • 隔离性
  2. 不考虑隔离性会引出一些问题: 脏读, 不可重复读, 幻读
  3. 这些问题 可以 隔离级别解决

实操-演示数据库安全性问题的发生

目标

  • 能够演示数据库安全性问题的发生

演示脏读

​ 一个事物里面读到了另外一个事物没有提交的数据: read uncommitted

  • 1.开启A,B窗口

  • 2.分别查询A,B的隔离级别

    select @@tx_isolation;
    
  • 3.设置A窗口的隔离级别为read uncommitted(读未提交)

    set session transaction isolation level read uncommitted;
    
  • 4.A,B都开启事物

  • 5.在B中zs向ls转账100,事务不提交

  • 6.在A中查询账户

解决脏读

​ 不可重复读: 在一个事物里面,同一条语句,两次查询的结果不一致.

  • 1.开启A,B窗口

  • 2.分别查询A,B的隔离级别

    select @@tx_isolation;
    
  • 3.设置A窗口的隔离级别为Read committed(读已提交)

    set session transaction isolation level Read committed;
    
  • 4.A,B都开启事物

  • 5.在B中张三向李四转账100,事物不提交

  • 6.在A中查询账户(避免脏读发生)

  • 7.B中提交事物

  • 8.在A中查询账户(两次查询的结果不一致,不可重复读发生)

解决不可重复读

  • 1.开启A,B窗口

  • 2.分别查询A,B的隔离级别

    select @@tx_isolation
    
  • 3.设置A窗口的隔离级别为Repeatable read

    set session transaction isolation level Repeatable read;
    
  • 4.A,B都开启事物

  • 5.在B中张三向李四转账100,事物不提交

  • 6.A中查询账户

  • 7.B中提交

  • 8.A中查询账户

  • 9.A中结束事物,再重新查询

演示隔离级别Serializable

  • 1.开启A,B窗口

  • 2.分别查询A,B的隔离级别

    select @@tx_isolation
    
  • 3.设置A窗口的隔离级别为Serializable

    set session transaction isolation level Serializable;
    
  • 4.A,B都开始事物

  • 5.B中向account账户插入一条数据,不提交

  • 6.A中查询

  • 7.在B中结束事物

  • 8.A中查询

猜你喜欢

转载自blog.csdn.net/Learning_xzj/article/details/125008428
今日推荐