事务的特性:
隔离性 , 原子性 , 一致性 , 持久性
引擎要选 innodb, 因为 myisam 不支持事务;
- create table t29 (
- id int,
- name char(10),
- money int
- )engine=innodb default charset=utf8;
插入 zhangsan 和 lisi 的数据
- insert into t29 values (1,'zhangsan',5000),(2,'lisi',5000);
如果不启动事务,zhangsan 借给 lisi 500, 即给 lisi 的钱 +500,zhangsan 的钱 -500;
先执行给lisi+500;如下:
- update t29 set money=money+500 where id=2;
在另一个窗口,我们去查看t29,会发现lisi这时的钱已经多了500,这个事务还没完成 ,zhangsan 的钱还没减 500,lisi 不应该看到自己多的 500;
之前就有这种骗术 , 一个人在柜台存钱 , 另一个人在 ATM 取钱,银行职员经过一系列操作 , 已经将钱转过去了,存钱的人在最后一步确认签字前 , 告诉银行职员 , 自己不存钱了;而取钱的人在收到钱的时候立刻就取出来,这个钱肯定无法扣除掉了 , 总不能为负数把 , 即使为负数 , 反正卡也不要了,在事务没有完成的中间状态 , 你不应该看到自己账户上多了钱;
一、事务的隔离性
A 窗口启用事务 , 来试一试 , 看看是什么样的效果
- start transaction;
先查看两个人各有多少钱 , 再次给 lisi+500
- select * from t29;
- update t29 set money=money+500 where id=2;
B 窗口查看 lisi 的钱
- select * from t29;
A 窗口应该给 zhangsan-500
- update t29 set money=money-500 where id=1;
B 窗口查看 t29
- select * from t29;
事务完成 ,A 窗口结束事务
- commit;
看不到事务的中间状态 , 只能看到事务的开始前的状态 , 和结束后的状态 , 这个叫做事务的 隔离性 ;
二、事务的原子性
commite 之后 , 事务就结束了;如果再想使用事务 , 需要重新 start transaction;
zhangsan 继续借给了 lisi500
- update t29 set money=money+500 where id=2;
- update t29 set money=money-500 where id=1;
结果在 commit 之前 , 想撤销借出的钱;需要用到 : 回滚 rollback;
- rollback;
- select * from t29;
B 窗口的 lisi, 无法看到 ,zhangsan 转了 500 半道又撤销了 , ,这叫做 隔离性;
三、事务的一致性
一致性指的是事务的之前和之后 , 它的业务逻辑上保持总体的一致;看以下代码演示:
- alter table t29 change money money int unsigned;
张三还剩下 4000, 如果他要借给 lisi5000, 能否成功呢 ?
- select * from t29;
- start transaction;
- update t29 set money=money+5000 where id=2;
- update t29 set money=money-5000 where id=1;
zhangsan 减钱的时候 , 他的钱已经不够 5000,money 字段不能为负数 , 所以 mysql 报错了;但是 mysql 它有几种语句的模式 , 有时候检测不是很严格 , 它存在一个语句检测模式问题;我们如果用严格模式 , 它超出存储范围 , 不能运行;如果采用的 sql_mod, 不是很严格 , 这句话是能够执行的;只不过它会将 zhangsan 的减 5000, 给减去 4000, 返回 0;那 zhangsan-4000,lisi+5000, 平白无故的多了 1000 => 合作生财之道;这个问题处在 , 汇款事务的前后 , 账面的总的额度变了 , 事务的一致性 , 指的就是事务前后的数据应该有保持 一致性;
四、事务的持久性
指的是 , 一旦 commit 之后 , 是无法回滚 rollback 的,因为 : 一旦 commit, 这个事实就已经发生了 , 就不可能撤销回去了;
例如 :取钱时 , 有可能发生 , 卡里的钱已经扣了 , 但是人民币没出来;遇到这种情况 , 不要离开 ATM 机 , 然后打银行电话;查看你的交易记录 , 确实是扣除了钱,不过还有一条 , 冲证记录,银行将钱又冲证 , 还给你了,一个事务发生了 , 是无法撤回的 , 只能再来一条补偿性的事务,将原来产生的恶果给你补偿回去;一个事情发生了 , 这就是铁一般的事实 , 这个流水在这呢 , 你不能将历史事实给去除,记录还是在的 , 这个就叫 持久性;