数据库事务ACID

suaxi
2020-11-02 / 0 评论 / 185 阅读 / 正在检测是否收录...

事务:要么都成功,要么都失败

1、A给B转账 A 1000 -->200 B 200

2、B收到A的钱 A 800 --> B 400

将sql放在一个批次中去执行

事务ACID原则:原子性,一致性,隔离性,持久性

原子性(Atomicity)

要么都成功,要么都失败

一致性(Consistency)

事务前后的数据完整性要保持一致(A、B一共有1000块钱,不论A和B怎么转账,最终两人钱的总和是1000块)

隔离性(Isolation)

多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离

持久性(Durability)

事务一旦提交则不可逆,事务提交的结果被持久化存储到数据库中

隔离所导致的一些问题
脏读:

指一个事务读取了另一个事务未提交的数据。

不可重读:

在一个事务内读取表中的某一行数据,多次读取的结果不同。(这个不一定是错误,需具体场景具体分析)

虚读(幻读):

指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

-- 事务
-- mysql是默认开启事务自动提交的
SET autocommit = 0; /*关闭*/
SET autocommit = 1; /*开启*/


-- 手动处理事务
-- 1、关闭自动提交
SET autocommit = 0; 

-- 2、事务开启
START TRANSACTION; -- 标记一个事务的开始,从这之后的sql都在同一个事务内

INSERT xx
INSERT xxx

-- 提交:持久化(成功)
COMMIT
-- 回滚:返回之前的状态(失败)
ROLLBACK

-- 3、事务结束
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(11) NOT NULL AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    money DECIMAL(9,2) NOT NULL,
    PRIMARY KEY (id)
)ENGINE=INNODB DEFAULT CHARSET=utf8;


INSERT INTO account(name,money) VALUES('a',1000.00),('b',500.00);


-- 模拟转账:事务
SET autocommit = 0; -- 关闭自动提交
START TRANSACTION -- 开启事务(一组事务)

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; -- 恢复默认提交
0

评论 (0)

取消