• mysql事务


    事务

    事务,一系列操作构成的逻辑单元。
    事务:当一个操作中的所有的小操作都执行成功这个操作才算执行成功时需要加事务。而这个“操作”就是一个事务。

    ACID

    原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持久性( Durability )
    Atomicity:原子的不可拆分的,一个不可拆分的工作单元,只有当工作单元中的所有操作都成功完成,这个工作单元才算成功完成,只要有一个操作失败,则认为工作单元失败。
    Consistency:不存在薛定谔的猫,事务提交之前 所有人看到的猫都是活的,事务提交之后 所有看到的猫都是死的

    • 事务提交之前,之后,数据库中的数据从一个一致性状态 到 另一个一致性状态,不存在中间状态
    • 事务未提交之前,不管这个事务内部对数据库中的数据进行了怎样的操作,他人无法查看未提交的事务对数据库数据的影响
      Isolation: 不同事务之间相互隔离,互不影响
      Durability: 事务提交之后,对数据库中数据的影响是持久的

    事务隔离级别

    隔离级别隔离级别值脏读不可重复读幻读
    Read-Uncommitted (未提交读)0
    Read-Committed (提交读)1
    Repeatable-Read (可重复读)2
    Serializable (可序列化)3

    隔离级别越高性能越低
    1个窗口1个session
    事务 autocommit:默认自动提交
    Repeatable-Read (可重复读): mysql InnoDB引擎 默认事务隔离级别
    Serializable (可序列化):前一个事务执行完成,才能执行后一个事务

    脏读:A事务未提交,B事务就去读(相同记录)
    幻读:事务A中已提交的新增记录,在事务B中查看不到,事务B中插入相同记录又会报错

    实验演示

    实验环境:mysql 5.7
    准备:

    # 创建数据库,COLLATE 排序规则
    CREATE DATABASE IF NOT EXISTS feature_tran DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
    # 使用库
    use feature_tran;
    # 创建表
    DROP TABLE IF EXISTS `employee`;
    CREATE TABLE `employee`  (
      `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
      `code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '工号',
      `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',
      `salary` float DEFAULT NULL COMMENT '薪水',
      `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic COMMENT = "员工";
    # 插入一条数据
    insert into employee(`code`,`name`,`salary`) value("1000000000","xcrj",1000.0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    脏读

    A事务未提交,B事务就去读(相同记录)
    下面的操作都只在当前session(窗口)中有效
    开启两个session,执行如下操作

    #关闭事务自动提交
    set autocommit = 0;
    #查看MySQL自动提交状态
    show variables like 'autocommit';
    #未提交读
    set session transaction isolation level READ UNCOMMITTED;
    #查看MySQL事务隔离级别
    show variables like 'tx_isolation';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    事务A事务B
    begin;
    begin;
    update employee set salary=2000.0 where code="1000000000";
    select salaryfrom employee wherecode="1000000000"; #2000.0,脏读
    rollback;
    select salaryfrom employee wherecode="1000000000";
    commit

    在这里插入图片描述

    不可重复读

    同一个事务中的两次读操作 记录数值不一致

    开启两个session,执行如下操作

    #关闭事务自动提交
    set autocommit = 0;
    #查看MySQL自动提交状态
    show variables like 'autocommit';
    #提交读
    set session transaction isolation level READ COMMITTED;
    #查看MySQL事务隔离级别
    show variables like 'tx_isolation';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    事务A事务B
    begin;
    begin;
    select salaryfrom employee wherecode="1000000000"; # 1000.0
    update employee set salary=2000.0 where code="1000000000";
    select salaryfrom employee wherecode="1000000000";# 2000.0,不可重复读
    commit
    commit

    在这里插入图片描述

    幻读

    事务A中已提交的新增记录,在事务B中查看不到,事务
    B中插入相同记录又会报错

    开启两个session,执行如下操作

    #关闭事务自动提交
    set autocommit = 0;
    #查看MySQL自动提交状态
    show variables like 'autocommit';
    #可重复读读
    set session transaction isolation level REPEATABLE READ;
    #查看MySQL事务隔离级别
    show variables like 'tx_isolation';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    事务A事务B
    begin;
    begin;
    insert into employee(id,code,name,salary) value(2,"1000000001","xcrj001",1100.0);
    select * from employee where name like "xcrj%"; # 1条记录
    commit;
    select * from employee where name like "xcrj%";# 还是1条记录
    insert into employee(id,code,name,salary) value(2,"1000000001","xcrj001",1100.0); #插入报错
    commit;

    在这里插入图片描述

    实验完毕

    #开启事务自动提交
    set autocommit = 0;
    #可重复读读
    set session transaction isolation level REPEATABLE READ;
    
    • 1
    • 2
    • 3
    • 4

    使用事务

    开始事务
    执行增删改查操作
    异常,回滚事务/正常,提交事务
    注意,未正常关闭(rollback/commit)的事务,会影响增删改查,因为事务的本质是锁

    xcrj 关闭未提交的事务

    事务未提交导致锁等待,影响增删改查

    #查询事务
    SELECT * from information_schema.INNODB_TRX;
    # 关闭事务。mysql自动回滚
    kill <trx_mysql_thread_id>
    
    • 1
    • 2
    • 3
    • 4

    常用命令

    #查看MySQL事务隔离级别
    show variables like 'tx_isolation';
    #查看MySQL自动提交状态
    show variables like 'autocommit';
    #关闭事务自动提交
    set autocommit = 0;
    #更改事务隔离级别
    #未提交读
    set global/session transaction isolation level READ UNCOMMITTED;
    #提交读
    SET global/session transaction isolation level READ COMMITTED;
    #可重复读
    SET global/session transaction isolation level REPEATABLE READ;  
    #可串行化
    SET global/session transaction isolation level SERIALIZABLE;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    shiro介绍和使用
    前后端分离&vue简介
    【os-tutorial】四,电脑存储的组织形式
    双功能连接试剂:Alkyne hydrazide,炔烃-酰肼 主要特点进行分享
    学习笔记:吴恩达ChatGPT提示工程
    python-opencv车牌检测和定位
    redis-cli写入超长转义字符串问题
    C++11改动
    短信上行和短信下行
    32.2.3 配置Atlas读写分离
  • 原文地址:https://blog.csdn.net/baidu_35805755/article/details/121878989