Mysql中的事务
文章目录
前言
Mysql中的事务。
一、Mysql中的事务是什么?
官话说:事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作 要么同时成功,要么同时失败。
简单说:
有这么一个事,小明要给小红转520红包。
这中间发生了什么呢?
第一件事:查询小明账户是否有520大洋。
第二件事:小明账户余额 减少 520大洋。
第三件事:小红账户余额 增加 520 大洋。
那么这三件事整体要看成一个事务,要么都成功,要么都失败。
情况一:
转成功:小明减少了520大洋,小红收到了520大洋。
情况二:
转失败:小明卡里没钱,小明账户余额不动,小红账户余额不动。
情况三:
转失败:小明卡里有钱,小明账户减少520,小红账户被冻结了,没法收钱,银行触发警告,此时当前整体事务需要回滚,小明账户减少的钱要加回来。
最终结果,小明账户余额不动,小红账户余额不动。
那么就可以总结事务是什么东西:
事务是一组操作的集合,这一组操作,要么全部执行成功,要么全部执行失败。
注意:默认MysQL的事务是自动提交的,也就是说,当执行一条DML语句,MysQL会立即隐式的提交事务。
二、事务能干什么
1.事务的存在是为了一切发生的小事,能按照规律进行因果转换。
当mysql 执行一串复杂的数据脚本,执行到一半的时候发生异常,能恢复到未执行的数据状态。
三、Mysql事务怎么使用?
(1)提前准备,创建账户表
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`money` int(11) DEFAULT NULL COMMENT '余额',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
(2)提前准备,创建两条数据
-- 新建两条数据
insert into account(id,name, money) VALUES (null,'张三',2000),(null,'李四',2000);
-- 恢复数据
update account set money = 2000 where name ='张三' or name ='李四';
(3)需要知道的几个命令
-- 查看/设置事务提交方式
SELECT @@autocommit;
-- 设置为手动提交
SET @@autocommit = 0;
-- 设置为自动提交
SET @@autocommit = 1;
-- 开启事务
START TRANSACTION;
-- 或
BEGIN;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
情况一:正常转账成功,转账操作 (张三给李四转账1000)
情况简述:转账操作 (张三给李四转账1000)
1.查询张三账户余额
2.将张三账户余额-1000
3.将李四账户余额+1000
-- 转账操作 (张三给李四转账1000)
-- 1.查询张三账户余额
select * from account where name ='张三';
-- 2.将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
-- 3.将李四账户余额+1000
update account set money = money + 1000 where name ='李四';
初始账户情况:
转账后结果:
小结:
1.默认MysQL的事务是自动提交的,也就是说,当执行一条DML语句,MysQL会立即隐式的提交事务。此时 @@autocommit = 1
2.每一条SQL都是单独的一个事务
情况二:转账失败,转账操作 (张三给李四转账1000)
情况简述:转账操作 (张三给李四转账1000)
1.查询张三账户余额
2.将张三账户余额-1000
3.出现网络波动,业务发生异常
4.将李四账户余额+1000
-- 转账操作 (张三给李四转账1000)
-- 1.查询张三账户余额
select * from account where name ='张三';
-- 2.将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
程序出现异常。。。网络波动
-- 3.将李四账户余额+1000
update account set money = money + 1000 where name ='李四';
初始账户情况:
转账后结果:
小结:
1.默认MysQL的事务是自动提交的,也就是说,当执行一条DML语句,MysQL会立即隐式的提交事务。此时 @@autocommit = 1
2.每一条SQL都是单独的一个事务
3.因为第三步,出现业务异常, 程序终止,没有执行第四步,所以只执行了第一步,第二步,所以导致数据没有一致性,张三钱扣了,而李四没有收到钱。
4.这种情况肯定是不科学的,正常李四没有收到钱,张三的钱应该原路返还,此时这种情况叫做数据回滚!
5.要想处理应该,把这几个步骤,整体作为一个事务,要么同时成功,要么同时失败!
情况三:转账失败,转账操作 (张三给李四转账1000)
情况简述:转账操作 (张三给李四转账1000)
设置数据库事务提交模式为,手动提交
1.查询张三账户余额
2.将张三账户余额-1000
3.出现网络波动,业务发生异常
4.将李四账户余额+1000
5.回滚事务!
-- 转账操作 (张三给李四转账1000)
-- 1.查询张三账户余额
select * from account where name ='张三';
-- 2.将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
程序出现异常。。。网络波动
-- 3.将李四账户余额+1000
update account set money = money + 1000 where name ='李四';
初始账户情况:
转账后结果(没有提交事务):
因为出现业务异常,不应该提交事务,如果提交事务就会造成,张三扣钱了,而李四没有收到钱。
因此现在需要,回滚!
-- 4.回滚事务
ROLLBACK;
转账后结果(进行数据回滚):
小结:
1.默认MysQL的事务是自动提交的,也就是说,当执行一条DML语句,MysQL会立即隐式的提交事务。此时 @@autocommit = 1
2.每一条SQL都是单独的一个事务
3.本阶段需要设置 @@autocommit = 0 手动提交事务
4.因为第三步,出现业务异常, 程序终止,没有执行第四步,所以只执行了第一步,第二步,所以导致数据没有一致性,张三钱扣了,而李四没有收到钱。而此时没有提交事务,所以数据还是跟之前的一样
4.这种情况一个事务开启,必须提交,或者回滚,当前步骤出现异常,此时这种情况叫做数据回滚!
5.执行回滚SQL 语句:ROLLBACK;
(4)事务的四大特性(ACID)
- 原子性 (Atomicity):
简单说: 情况一的几个步骤,是事务的最小单位,要么全部执行成功。要么全部执行失败。
- 一致性(Consistency):
简单说: 情况一正常转账,张三和李四的钱,加起来应该和初始值一样,一共4000大洋。
- 隔离性(lsolation):
简单说:情况一,情况二,情况三,都是单独的事务,互不影响,完全隔离,后面会说一下,mysql 的隔离级别!
- 持久性 (Durability):
简单说:数据的处理,最终会有一个最终状态,那么就会留痕,数据库里的数据,最终也是落在磁盘中,永久保存。
总结
mysql 的事务,与spring的事务,原理是一样的,都是针对数据的操作,保证事务的四大特性.