1.事务
1.1 什么是事务?
将一组SQL语句放在一个批次中执行,要么都成功,要么都失败。
例如:A给B转200元,A开始有1000元,B开始有500元。
SQL语句1:A给B转账200
SQL语句2:B收到A的200
这两句话必须同时执行或不执行,单有一句执行则钱会凭空消失或增加。
1.2 事务原则 (ACID)
原子性(Atomicity):事务中要么都成功,要么都失败(上述SQL1,2同时执行)
一致性(Consistency):事务前后的数据完整性要保持一致(钱不会变多或少)
持久性(Durability):一旦事务提交就不可逆转,被持久化到数据库中(转账后A和B的状态不会逆转到转帐前A和B的状态)
隔离性(Isolation):事务产生多并发时,互不干扰(A给B转和B给C转是两个事务,不会互相干扰)
隔离失败产生的问题:脏读、不可重复读、幻读
脏读
指一个事务读取了另外一个事务未提交的数据。
事务一①③和事务二②④分别是C给B转账和A给B转账的两个事务。若按照①②③④顺序转账,则事务一读取了未提交的事务二(即步骤②),导致脏读。正确应该是①②④③,等事务二提交后(完成步骤④后),再执行事务一。
不可重复读
在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)
页面统计查询值
生成报表的时候,B有人转账进来300(B事务已经提交)
虚读(幻读)
是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一般是行影响,多了一行)
1.3 事务基本流程
MySQL中是默认开启事务自动提交(autocommit)的,导致每执行一句sql都会提交一个事务,所以处理事务前要手动关闭事务自动提交,事务结束后再开启事务自动提交。
SET autocommit=0 -- 关闭事务自动提交
SET autocommit=1 -- 开启事务自动提交(MySQL默认)
1.3.1 事务流程
-- 处理事务流程
-- step1:关闭自动提交
-- 注意:MySQL中是默认开启事务自动提交的,每执行一句sql都会提交一个事务,所以处理事务前要手动关闭事务自动提交,事务结束后再开启事务自动提交
SET autocommit = 0
-- step2:开启事务
START TRANSACTION
INSERT XX -- SQL语句1
INSERT XX -- SQL语句2
-- step3:提交:提交事务(事务成功)
COMMIT
-- step3:回滚:回到原来的样子(事务失败)
ROLLBACK
-- step4:结束事务
SET autocommit = 1 -- 开启自动提交
1.3.2 模拟事务流程(转账)
① 创建数据库和表
② 模拟转账
-- 事务:A给B转500元
SET autocommit = 0; -- 关闭事务自动提交
START TRANSACTION;
UPDATE account SET money = money-500 WHERE `name` = 'A';
UPDATE account SET money = money+500 WHERE `name` = 'B';
COMMIT; -- 一旦事务提交,就被持久化了,事务就不可逆转了
ROLLBACK;
SET autocommit = 1; -- 恢复MySQL默认的事务自动提交