六、事务
将一组MySQL放在一个批次中执行 以转账为例
事务原则:ACID原则:原子性、一致性、隔离性、持久性(脏读、幻读…)
原子性(Atomicity)
事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
要么都成功,要么都失败!
一致性(Consistency)
事务前后数据完整性保持一致。
隔离性(Isolation)
多个用户并访问数据库时,数据库为每一个用户开启的事务,不能被其它事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
事务的隔离级别(隔离导致的一些问题):
脏读:
指一个事务读取了另一个事务未提交的数据。
不可重复读:
在一个事务内读取表中的某一行数据,多次读取结果不同。(这不一定是错误,只是某些场合不对。)
虚读(幻读):
是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一般是行影响,多了一行。)
参考CSDN博客链接:https://blog.csdn.net/dengjili/article/details/82468576
执行事务(原理):
mysql是默认开启事务自动提交的
关闭:
SET autocommit = 0
开启(默认的):
SET autocommit = 1
--手动处理事务
SET autocommit = 0 --关闭自动提交
--事务开启
START TRANSACTION --标记一个事务的开始,从这个之后的sql都在同一个事物内
INSERT…
INSERT… --只要有失败的,事务就提交不上去
--提交:持久化(成功!)
COMMIT
--回滚:回到原来的样子(失败!)
ROLLBACK
--事务结束
SET autocommit = 1 --开启自动提交
--事务过长,中途可利用保存点
SAVEPOINT 保存点名 --设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名 --回滚到保存点
RELEASE SAVEPOINT 保存点名 --撤销保存点
模拟转账:
--创建账户数据库和表并插入数据
CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci
USE shop
CREATE TABLE `account` (
`id` INT(3) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL,
`money` DECIMAL(9,2) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO account(`name`,`money`) VALUES (`A`,2000.00),(`B`,10000.00)
--模拟转账事务
SET autocommit = 0 --关闭自动提交
START TRANSACTION --开启一个事务(一组事务)
--A转账500元给B
UPDATE account SET money=money-500 WHERE `name`='A' --A减500元
UPDATE account SET money=money+500 WHERE `name`='B' --B加500元
COMMIT; --提交事务后被持久化
ROLLBACK; --回滚
SET autocommit = 1 --恢复默认值