MySQL学习笔记之事务(上)(十三)
程序员文章站
2022-07-12 13:53:54
...
事务的基本介绍
- 概念
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败 - 操作
1.开启事务:start transaction
2.回滚:rollback
3.提交:commit
我们在介绍事务之前先新建一个表单:
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME , balance)VALUES ('zhangsan',1000),('lisi',1000);
SELECT * FROM account;
运行效果:
我们接下来写以下以下案例:
张三给李四转账500元
**(一)**查询张三账户余额是否大于500
**(二)**张三账户余额 -500
**(三)**李四账户余额 +500
我们试试普通的转账:
-- 1.张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2.李四账户 +500
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
运行效果:
接下来我们制造异常试试,我们先回复为1000元
然后执行以下代码:
-- 1.张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2.李四账户 +500
出错了...
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
运行效果:
可以看到500块钱不翼而飞,我们可以用事务管理来避免这样的问题
我们先还原为1000块钱
-- 0.开启事务
START TRANSACTION;
-- 1.张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2.李四账户 +500
出错了...
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 3.发现执行没有问题,提交事务
COMMIT;
-- 4.发现出问题了,回滚事务
ROLLBACK;
运行效果:
MySQL数据库中事务默认自动提交
- 一条DML(增删改)语句会自动提交一次事务,注意是自动提交!
- 而我们刚才的操作是手动提交
如果我们开启了事务(即START TRANSACTION;)而没有手动提交(即COMMIT;),事务就会自动回滚(即ROLLBACK;)
如下:
-- 0.开启事务
START TRANSACTION;
-- 1.张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2.李四账户 +500
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
执行之后如下:
看似转账成功了,其实这只是临时文件,我们关闭SQLyog窗口再次打开就恢复为1000块钱了,也就是说自动回滚了
查看事务的默认提交方式
其中1代表自动提交、0代表手动提交
修改事务的默认提交方式
如果改成0而不手动提交,则所有DML操作在关闭SQLyog那一刻都会被回滚
手动提交:
这里顺带提一下:Oracle数据库默认是手动提交事务的
事务的四大特征
- 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败
- 持久性:当事务提交或回滚后,数据库会持久化的保存数据
- 隔离性:多个事务之间相互独立
- 一致性:事务操作前后,数据总量不变
事务的隔离级别
- 概念:多个事务之间是隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题
- 存在的问题:
1.脏读:一个事务读取到另一个事务中没有提交的数据
2.不可重复读:在同一个事务中,两次读取到的数据不一样
3.幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改 - 隔离级别:
1.read uncommitted:读未提交
产生的问题:脏读、不可重复读、幻读
2.read committed:读已提交 (Oracle默认)
产生的问题:不可重复读、幻读
3.repeatable read:可重复读 (MySQL默认)
产生的问题:幻读
4.serializable:串行化
可以解决所有的问题 - 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
- 数据库查询隔离级别:
select @@transaction_isolation;
- 数据库设置隔离界别:
set global transaction isolation level 级别字符串;
注意:重新设置了隔离级别后要重启MySQL
下一篇: GO标准库学习笔记-错误(errors)