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;