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

posted @ 2022-12-22 11:11  YorkShare  阅读(30)  评论(0编辑  收藏  举报