MySQL事务
1.事务的概念
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败。如:网上转账就是典型的要用事务来处理,用以保证数据的一致性。
2.事务的特点
核心:将一组SQL放在一个批次中去执行
事务原则:ACID原则,原子性、一致性、隔离性、持久性 (脏读,幻读....)
ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。
例1.模拟转账情景(转自:https://blog.csdn.net/zhoulv163/article/details/127072132)
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), PRIMARY KEY (`id`) )ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO `account`(`name`,`money`) VALUES ('A',2000.00),('B',10000.00); select * from `account`; -- 模拟转账 -- 手动处理事务 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; -- 开启自动提交 select * from `account`;
此时rollback在commit之后,回滚失败,A成功转账给B。
注意:(1)当我们开启(手动)事务之后,其后一系列操作并没有直接写入数据库,而是存入了事务日志,在运行到commit之前,重新启动一个新的客户端,查看account表的数据,发现account表的数据没有任何变化,如果我们选择提交事务,则将事务日志存储的记录直接更新到数据库,并清除事务日志;如果我们选择回滚事务,则直接将事务日志清除,所有在开启事务至回滚事务之间的操作失效,保持原有的数据库记录不变。
(2)当我们提交事务之后,再进行回滚事务是不起作用的,因为事务日志在提交事务的同时已经被清除啦!
将rollback置于commit之前,再进行一次转账,如下:
-- 模拟转账 -- 手动处理事务 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 -- 回滚:回到原来的样子 ROLLBACK; -- 提交事务 COMMIT; -- 恢复默认值 SET autocommit=1; -- 开启自动提交 select * from `account`;
此时转账失败,表中的值不变。
例2:创建多个保存点(savepoint),回滚到某个保存点(rollback to)。(转自:https://www.cnblogs.com/lsqbk/p/10145306.html)
执行以下事务之前,数据库原始表的数据是:
执行以下事务之后:
start TRANSACTION; #开始一个事务 SAVEPOINT a; #做一个保存点a DELETE from account where name='B'; #先删除一行记录 SAVEPOINT b; #做一个保存点b update account set money=money+1000 where name='A'; #修改A的字段值 SAVEPOINT c;#做一个保存点c ROLLBACK to b;#回退到指定的某个保存点 COMMIT;#提交事务
此时,name为B的记录以及被删除,而name为A的记录money没有增加1000。
事务的细节
(1) 没有设置保存点
开始事务时,事务会默认给你创建一个保存点,如果你希望回退也可以使用rollback , 就可以直接回退到事务开始的状态.
(2) 多个保存点
我们可以设置多个保底点,但是如果我们回退时,需要按顺序回退。即如果你回退到前面的某个保底点,那么后面的保存点就没有了.
(3) 存储引擎
如果要支持事务,需要存储引擎是 innodb;
(4) 开始事务方式
start transaction;
set autocommit = false;
参考文章:
https://baijiahao.baidu.com/s?id=1722528612965200674&wfr=spider&for=pc
https://www.cnblogs.com/lsqbk/p/10145306.html
https://blog.csdn.net/zhoulv163/article/details/127072132