MySQL基础(五)——事务
作者:木子六日;
sql版本:5.7.33;
文章目录
- MySQL基础(五)——事务
- 创建事务
- 事务的隔离级别
创建事务
# 事务:一个或者一组sql语句视为一个执行单元,要么全部成功,要么全部失败;
/*
事务的ACID属性:
原子性(Atomicity):事务是一个不可分割的工作单位,要么发生,要么不发生;
一致性(Consistency):事务必须使数据库从一个状态变换到另一个状态;
隔离性(Isolation):并发执行的事务之间不能相互干扰;
持久性(Durability):事务一旦被提交,对数据库的改变就是永久的,不可更改;
*/
# 事务的创建
# 隐式事务:insert、update、delete这些都是默认开启事务的;
# 显示事务的创建
-- create TABLE account(
-- id int PRIMARY key auto_increment,
-- username VARCHAR(20),
-- balance double
-- );
--
-- insert into account(username,balance)
-- values
-- ('张无忌',1000),
-- ('周芷若',1000);
# 开启事务
SET autocommit = 0;
#关闭自动提交
START TRANSACTION;
#这句写不写都行,关了自动提交会开启事务
#一组sql语句
UPDATE account
SET balance = 0
WHERE
username = '张无忌';
UPDATE account
SET balance = 2000
WHERE
username = '周芷若';
# 提交或者回滚
COMMIT;
# ROLLBACK;
# SAVEPOINT就是设置一个存档点,可以回滚到指定存档位置
# SAVEPOINT的使用
SET autocommit = 0;
START TRANSACTION;
INSERT INTO account
SET username = 'ljj';
SAVEPOINT a;
INSERT INTO account
SET username = '李晶晶';
ROLLBACK TO a;
事务的隔离级别
# 事务的隔离级别
/*
mysql支持四种事务隔离级别:
READ UNCOMMITTED:读未提交
READ COMMITTED:读已提交
REPEATABLE READ:可重复读
SERIALIZABLE:串行化
*/
/*
三大并发问题:
脏读:
事务A和事务B,A事务更新了x字段,还未提交
B事务随后查询了x字段,读取了A还未提交的结果
A事务是有可能回滚的,所以B读取了一个不该存在的值
脏读的情况发生在隔离级别为READ UNCOMMITTED时
一旦将隔离界别提升至READ COMMITTED,B就无法查出A事务还未提交的结果。
不可重复读:
事务A和事务B,A事务更新了x字段,还未提交
此时B查询了x字段,结果为更新前的值
A事务随后提交,B又查了一遍x字段,结果为更新后的值
B事务的两次查询出现不同结果
即一次事务内同一查询出现不同的结果,这是不能接受的
不可重复读出现在隔离界别为READ COMMITTED时
一旦将隔离级别提升至 REPEATABLE READ,B事务一旦开启,无论查询几次结果都是一样的
幻读:
事务A和事务B,事务B查询了一下表y共有z条记录
此时事务A向y中插入了一条记录并提交
B想更新查询出来的z条记录,结果更新了z+1条记录
幻读出现在隔离级别为 REPEATABLE READ及以下时
解决幻读需将隔离级别提升至 SERIALIZABLE
这时在B查询表后,表y将一直被B事务占有,A事务的插入操作将被阻塞,直至B提交
虽然 SERIALIZABLE隔离界别能解决上述三大问题
但是效率很低
*/
# 查看当前默认的隔离级别(REPEATABLE READ)
SELECT
@@tx_isolation;
# 设置会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
# 设置全局隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;