一组SQL在同一批次内执行,要么都成功, 要么都失败
1. 事务原则ACID
1.1 原子性
要么都成功,要么都失败
1.2 一致性
事务前后的数据完整性保证一致
1.3 持久性
事务一旦提交则不可逆,持久化到数据库中
1.4 隔离性
多个用户同时访问数据库时,数据库为每一个用户开启的事务不能被其他事务的操作数据所干扰,事务之间要相互隔离
隔离级别
脏读:一个事务读取了另一个事务未提交的数据
不可重复读:一个事务读取表中某一行数据,多次读取结果不同(某些场景)
幻读:在一个事务内读取到别的事务插入的数据,导致前后读取不一致
手动处理事务
-- mysql默认开启事务自动提交
SET autocommit=0 /* 关闭 */
SET autocommit=1 /* 开启 */
-- 手动处理事务
SET autocommit=0 /* 关闭自动提交 */
-- 事务开启
START TRANSACTION
INSERT
-- 提交:持久化(成功)
COMMIT
-- 回滚:回到起始状态(失败)
-- 事务结束
SET autocommit=1 /* 开启自动提交 */
SAVEPOINT `保存点` /* 设置一个事务的保存点 */
ROLLBACK TO SAVEPOINT `保存点` /* 回滚到保存点 */
RELEASE `保存点` /* 删除保存点 */
模拟退货
-- 退货
CREATE DATABASE `shop` CHARACTER SET utf8 COLLATE utf8_general_ci
USE shop
CREATE TABLE `supermaket`(
`goods_id` INT(10) NOT NULL AUTO_INCREMENT,
`goods_name` VARCHAR(20) NOT NULL,
`stock` DECIMAL(10) NOT NULL,
PRIMARY KEY (`goods_id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `supermaket`
VALUES('120001','OPPO X',1),('120002','OPPO X',0)
-- 模拟退货
SET autocommit=0 -- 关闭自动提交
START TRANSACTION -- 开启一个事务
UPDATE supermaket SET stock=stock-1 WHERE `goods_id`='120001'
UPDATE supermaket SET stock=stock+1 WHERE `goods_id`='120002'
COMMIT -- 提交
ROLLBACK -- 回滚
SET autocommit=1 -- 恢复默认值