2022.4.1 mysql事务

事务

1.什么是事务

要么都成功,要么都失败

将一组SQL放在一个批次中去执行

事务原则:ACID原则 原子性,一致性,隔离性,持久性 (脏读,幻读)

事务管理(ACID) 谈到事务一般都是以下四点

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

  • 一致性(Consistency) 事务前后数据的完整性必须保持一致。

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

  • 持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

举个简单的例子理解以上四点

原子性(Atomicity)

针对同一个事务

 

这个过程包含两个步骤

A:800 - 200 = 600 B:200 + 200 = 400

原子性表示,这两个步骤一起成功,或者一起失败,不能只发生其中一个动作

一致性(Consistency)

针对一个事务操作前与操作后的状态一致

 

操作前A:800,B:200 操作后A:600,B:400

一致性表示事务完成后,符合逻辑运算,总和必须是1000,不能少也不能多

持久性(Durability)

表示事务结束后的数据不随着外界原因导致数据丢失

操作前A:800,B:200 操作后A:600,B:400 如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为 A:800,B:200 恢复到起始状态 如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为 A:600,B:400 持久化到数据库

事务一旦提交就不可逆

隔离性(Isolation)

针对多个用户同时操作,主要是排除其他事务对本次事务的影响

 

事务一)A向B转账200 事务二)C向B转账100

两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据,执行步骤如图所示,按照数字顺序执行

 

隔离性用于解决以上问题

2. 事务隔离产生的问题

脏读

指一个事务读取了另外一个事务未提交的数据。

不可重复读:

在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)

页面统计查询值

生成报表的时候,B有人转账进来300(B事务已经提交)

虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取数量总量不一致。 (一般是行影响,如下图所示:多了一行,(事务A查询id=1不存在,之后事务B插入id=1,事务A插入id=1发现已经存在 ))

并发事务隔离级别:

隔离级别脏读不可重复读幻读
Read uncommitted
Read committed ×
Repeatable Read(mysql默认) × ×
Serializable × × ×
  • √表示在当前隔离级别下该问题会出现

  • Serializable 性能最低;Read uncommitted 性能最高,数据安全性最差

  查看事务隔离级别: SELECT @@TRANSACTION_ISOLATION;

  设置事务隔离级别: SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }; SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效

 
案例:
 1  --默认MysQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。
 2  SET autocommit = 0 -- 关闭
 3  SET autocommit = 1 -- 开启(默认的)
 4  5  -- 手动处理事务
 6  SET autocommit = 0 -- 关闭自动条件
 7  8  -- 事务开启
 9  START TRANSACTIONBEGIN    -- 标记一个事务的开始,从这个之后的sql 都在同一个事务内
10 11  -- 提交:持久化(成功!)
12  COMMIT
13  -- 回滚:回到|的原来的样子(失败!)
14  ROLLBACK
15 16  -- 事务结束
17  SET autocommit = 1 -- 开启(默认的)
18 19  -- 了解
20  SAVEPOINT 保存点名 -- 设置一个事务的保存点
21  ROLLBACK TO SAVEPOINT 保存点名 -- 回滚到保存点
22  RELEASE SAVEPOINT 保存点名 -- 删除保存点
 
 1  -- 创建一个数据库
 2  CREATE DATABASE shop
 3  CHARACTER SET utf8 COLLATE utf8_general_ci
 4  5  USE shop -- 使用数据库
 6  7  CREATE TABLE `account`(
 8    `id` INT(3) NOT NULL AUTO_INCREMENT,
 9    `name` VARCHAR(30) NOT NULL,
10    `money` DECIMAL (9,2) NOT NULL,
11    PRIMARY KEY (`id`)
12  )ENGINE=INNODB DEFAULT CHARSET=utf8
13 14  INSERT 
15  INTO account( `name`, `money`)
16  VALUES ( 'A',2000.00),('B',10000.00)
17 18  -- 模拟转账:事务
19  SET autocommit = 0 -- 关闭自动条件
20 21  START TRANSACTION -- 开启事务    
22 23  UPDATE account
24  SET money=money-500
25  WHERE `name`='A';
26 27  UPDATE account
28  SET money=money+500
29  WHERE `name`='B';
30 31  COMMIT;  -- 提交事务,就被持久化
32  ROLLBACK; -- 回滚
33 34  SET autocommit = 1 -- 恢复默认值
35  
posted @ 2022-04-02 17:57  暴躁C语言  阅读(240)  评论(0)    收藏  举报