Java学习-MySQL-事务
ACID原则:原子性、一致性、隔离性、持久性
原子性(Atomicity)
两个步骤要么一起成功,要么一起失败,不可能只成功一个。
举例: A账户400元,B账户600元,A向B转账200元,要么转账成功,A账户剩余200元,B账户800元,要么转账失败,A账户还是400元,B账户600元,不可能存在A账户转账成功剩余200元,B账户没有收到转账还是600元,或者A账户没有扣费还是400元,B账户已经到账变成800元。
一致性(Consistency)
操作前与操作后的状态一致。
举例: 转账前A账户400元,B账户600元,总和1000元,转账后A账户剩余200元,B账户800元,总和还是1000元.
隔离性(Isolation)
多个拥护同时操作,排除其他事务对本次事务的影响。
持久性(Durability)
事务结束后的数据不会随着外界原因导致数据丢失。事务一旦提交则不可逆,被持久化到数据库中。
脏读
一个事务读取了另一个事务未提交的数据
举例: A账户400元,B账户600元,C账户200元,A账户读取到B账户的余额,在向B账户转账200元的时候,C账户读取到B账户的余额还有600元,向B账户转账100元。A账户转账成功,显示B账户的余额为800元,C账户转账成功,显示B账户的余额为700元。
幻读
在一个事务内读取到了其他事务插入的数据,导致前后读取不一致
流程
-- 关闭事务自动提交
SET autocommit=0
-- 事务开启
START TRANSACTION
INSERT xx
INSERT xx
-- 提交:持久化(成功)
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(20) NOT NULL,
`money` DECIMAL(9,2) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `account`(`name`,`money`)VALUES
('A',8000),('B',10000)
转账
SET autocommit=0
START TRANSACTION
UPDATE `account` SET `money`=`money`-5000 WHERE `name`='A'
UPDATE `account` SET `money`=`money`+5000 WHERE `name`='B'
未提交,回滚,回到初始状态
ROLLBACK;
提交,数据持久化
UPDATE `account` SET `money`=`money`-5000 WHERE `name`='A'
UPDATE `account` SET `money`=`money`+5000 WHERE `name`='B'
COMMIT;
再次回滚只能维持新的状态,无法回到提交前的状态
ROLLBACK;
SET autocommit=1