Mysql数据库系列(三)Mysql中的事务

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)

在这里插入图片描述

  1. 原子性 (Atomicity):

简单说: 情况一的几个步骤,是事务的最小单位,要么全部执行成功。要么全部执行失败。

  1. 一致性(Consistency):

简单说: 情况一正常转账,张三和李四的钱,加起来应该和初始值一样,一共4000大洋。

  1. 隔离性(lsolation):

简单说:情况一,情况二,情况三,都是单独的事务,互不影响,完全隔离,后面会说一下,mysql 的隔离级别!

  1. 持久性 (Durability):

简单说:数据的处理,最终会有一个最终状态,那么就会留痕,数据库里的数据,最终也是落在磁盘中,永久保存。

总结

mysql 的事务,与spring的事务,原理是一样的,都是针对数据的操作,保证事务的四大特性.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜良配情深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值