MySQL事务
事务的意义
案例:银行转账过程
A向B转账500,A原来有1000,B有500。
分析:
SQL处理过程:
A 减少 500
B 增加 500
以上两点必须同时生效,才算合理。
核心:要么都成功,要么都失败
事务(Transaction):一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)
事务管理(ACID)
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
以上述例子为例:
转账成功:A 转出500,B转入500是同时发生的。
转账失败:A 转出500失败,B不会转入500。
转账要么都成功,要么都失败,不能只发生一个动作,比如A少了500,但B没加。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
无论怎么转总价值 1500,不会少。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务没有提交,则恢复到原状
事务如果提交,则不可逆
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
A给B转账,C给B转账。两个是独立的,不会相互影响。
常见问题
脏读
指一个事务读取了另一个事务未提交的数据。
举例:
A :1000 B:500 C:1000
首先A 转账给B 500,记为事务1,此时A:500 B:1000,但事务没结束,结果还未提交。
这时C 也转账给B 500,该事务中B的初始值是500,C是1000,转账后 B:1000 ,C:500。
事务1提交结果,A:500,B:1000。
事务2提交结果,B:1000,C:500。
最后结果:A:500 B:1000 C:500,B 少了500!
错误原因是事务2读取的B的余额不准确。
不可重复读
在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)
比如报表功能,包含查询、生成报表,查询的时候,A :1000 B:500。在生成报表前,提交A完成转账500给B的事务,最终生成的报表中,A:500,B:1000
虚读(幻读)
和上面类似,是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
(一般是行影响,多了一行。)
执行事务
MySQL是默认开启事务自动提交的,需要关闭。语句如下:
SET autocommit = 0 -- 关闭
SET autocommit = 1 -- 开启(默认的)
手动处理事务:
关闭事务自动提交 SET autocommit = 0
开启事务(标记一个事务的开始,之后的语句都在同一个事务内) Start transaction
写SQL语句……
执行操作
提交(成功,持久化到数据库) commit
回滚(失败,回到原来的样子) rollback
事务结束
打开事务自动提交
其他(了解即可)
事务语句较多时,可以设置保存点 savepoint
回滚到保存点 rollback to savepoint
释放保存点 release savepoint
案例:实现一个转账事务,A向B转账500
-- 创建数据库 Bank
CREATE DATABASE `Bank` CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 创建表
CREATE TABLE `account`(
`id` INT(4) AUTO_INCREMENT NOT NULL,
`name` VARCHAR(20) NOT NULL,
`money` DECIMAL(9,2) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE INNODB DEFAULT CHARSET=utf8;
-- 插入A和B的账户数据
INSERT INTO `account`(`name`,`money`) VALUES ('A','1000.00'),('B','500.00');
-- 转账事务处理
-- 关闭事务自动提交
SET autocommit=0;
-- 开启事务
START TRANSACTION;
-- 写SQL语句
-- A - 500
UPDATE `account` SET money=money-500 WHERE `name`='A';
-- B + 500
UPDATE `account` SET money= money+500 WHERE `name`='B';
-- 提交事务
COMMIT;
-- 重新打开事务自动提交
SET autocommit=1;
以上为事务相关的基础内容学习记录及案例练习。