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 TRANSACTION 或 BEGIN -- 标记一个事务的开始,从这个之后的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

浙公网安备 33010602011771号