MySQL 基础-事务处理

104 阅读3分钟

概述

通俗来讲事务就是多步操作要么全部成功要么全部失败,保证最终状态一致。 为了简化应用程序,使其可以忽略一些潜在错误和并发问题,数据库层对事务的ACID特性做了统一支持。

事务的基本特性

事务有四大特性:原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability),俗称:ACID

  • 原子性(Atomicity)
    要么一起成功,要么一起失败

  • 一致性(Consistency)
    事务前后的数据完整性要保证一致

  • 持久性(Durability)
    事务一旦提交则不可逆,持久化到数据库中

  • 隔离性(Isolation)
    事务的隔离性是多用户并发访问数据库时,数据库为每一个用户开始的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要有隔离性

    • 脏读
      指一个事务读取了另外一个事务未提交的数据
    • 不可重复读
      在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误的,只是某次场合不对)针对update操作
    • 虚读(幻读)
      是指在一个事务内读到了别的事务插入的数据,导致前后读取不一致 针对inset和delete操作

事务的基本操作

   -- mysql 是默认开启事务自动提交的
   set autocommit = FALSE  -- 关闭 指事务非自动提交 
   set autocommit = TRUE  -- 默认开启 
   savepoint [保存点名] -- 设置一个事务的保存点
   rollback --  全部回滚
   rollback to savepoint [保存点名] -- 回滚到保存点
   commit  -- 提交事物,所有的操作
   release savepoint  [保存点名] -- 撤销一个保存点
   
   start transaction; -- 开启事物
   select @@transaction_isolation; --查看隔离级别
   
   -- 设置当前 MySQL 连接的隔离级别
   set session transaction isolation level read committed;
   -- 设置数据库系统的全局的隔离级别
   set global transaction isolation level [read uncommitted | read committed | repeatable read | serializable];
   
   select * from account;
       update account set uname = 'tom' where id = 100;
       update account set money = 1300 where id = 100;
   update account set money = 1600 where id = 100;
   insert into account values(200,'lala',2000);

显示事务

START TRANSACTION 或者 BEGIN,作用是显示开启一个事务 START TRANSACTION 后面可以追加 修饰符

  1. READ ONLY 标识当前事务是一个只读事务,也就是属于该事务的数据库操作只能读取数据,而不能修改数据

补充:只读事务中只是不允许修改哪些其他事物也能访问到的表中的数据,对于临时表来说(我们使用 CREATE TEMPORARY TABLE 创建的表),由于它们只能在当前会话中可见,所以只读事物其实也是可以对临时表进行增、删、改操作的

  1. READ WRITE (默认)
  2. WITH CONSISTENT SHAPSHOT 启动一致性

事务隔离级别

它们分别会对应一些并发问题,如表格所示:

隔离级别脏读不可重复读幻读加锁读
读未提交(read uncommitted)V\color{#00a73a}{V}V\color{#00a73a}{V}V\color{#00a73a}{V}X\color{#a40303}{X}
读已提交(read committed)X\color{#a40303}{X}V\color{#00a73a}{V}V\color{#00a73a}{V}X\color{#a40303}{X}
可重复读(repeatable read)X\color{#a40303}{X}X\color{#a40303}{X}V\color{#00a73a}{V}X\color{#a40303}{X}
可串行化(serializable)X\color{#a40303}{X}X\color{#a40303}{X}X\color{#a40303}{X}V\color{#00a73a}{V}

注意:可重复读(repeatable read) 模式幻读出现在,更新了一个其他事务插入的值时才会出现

image.png

mysql1开启事务,执行 update account set uname = 'tom' where id = 100;

image.png

此时mysql2也开启事务,并查询数据库数据,此时数据未改变,然后执行update account set money = 1300 where id = 100; 发现进程等待

image.png

mysql1 执行commit; 查看数据

image.png

mysql1 执行commit;完后mysql2进程等待解除 更新完成了 update account set money = 1300 where id = 100;的操作,此时 mysql2还未commit;,但是 uname 执已近更新,所以出现幻读

image.png

最终数据如下

image.png