1.事务是什么:
- 概念:事务就是一个流程,要么都完成,要么流程中一个过程失败,整个流程就失败。
例子:
/*
好比银行存钱:
存钱的流程为:拿出银行卡->插卡->输入密码->存钱。
以上存钱的流程为一个事务流程,我们可以运用逻辑和生活常识得出,这个流程中哪怕一环出错,
比如密码输错三次,那么你都存不了钱,存钱的这个事务就失败了。
我们把流程中的四个步骤分别抽象成四句SQL语句
那么这四条SQL语句就组成了数据库中的事务,四条SQL语句放到一个批次中依次执行完成才能提交事务。
换句话说,事务具有原子性。
*/
2.事务的原则:
ACID原则:
- 原子性(Atomicity):要么都执行,要么都不执行。
- 一致性(Consistency):事务前后的数据保持完整。
- 隔离性(Isolation):多个事务之间相互隔离,事物执行中不会干扰。
- 持久性(Durability):事务一旦完成,那么就是永久改变的,不可逆的,不会因为外界的原因导致数据丢失。
事务的隔离可能所导致的问题:
- 脏读:事务并发运行中,一个事务读取了另一个事务未提交的数据。
- 幻读:在一个事务内读取到了别的事物插入的数据,一般都是多了一行。
- 不可重复读:
- 事务在读取一行数据的时候,多次读取结果都不一样。
- 好比我给你转钱,第一次转完之后又转第二次,前后两次读表的数据都不一样,因为你的钱是在变的,出现不可重复读的事不一定是出错了,也可能是场合不对。
3.与事务有关的一些语句:
MySQL中默认开启事务自动提交。
- 具体开关是与这条语句有关:
SET AUTOCOMMIT = 0; -- 0为关闭。
SET AUTOCOMMIT = 1; -- 1为开启。
- 与事务的开启有关的语句:
START TRANSACTION; -- 设置事务开启点。
- 有关保存点:
SAVEPOINT name; -- 设置保存点。
RELEASE SAVEPOINT name; -- 释放指定保存点。
ROLLBACK SAVEPOINT name; -- 事务回滚到指定保存点。
- 事务处理的整个逻辑过程为:
/*
关闭事务自动提交状态 → 设置事务开启点 → 执行事务SQL → [保存点] →
成功:提交事务,失败:回滚(到保存点) → 开启事务自动提交(结束)
*/
SET AUTOCOMMIT = 0;
START TRANSACTION;
SQL...
SAVEPOINT ...;
COMMIT ...;
ROLLBACK ...;
SET AUTOCOMMIT = 1;
4.尝试模拟银行转账事务:
表和数据的准备过程:
-- 创建银行数据库:
CREATE DATABASE `bank` CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 使用银行数据库:
USE `bank`;
-- 在银行数据库下创建账户表:
CREATE TABLE `bank`.`account`(
`no` INT(4) NOT NULL AUTO_INCREMENT COMMENT '卡号',
`name` VARCHAR(10) DEFAULT NULL COMMENT '持卡人姓名',
`money` DECIMAL(10,2) NOT NULL COMMENT '账户余额',
PRIMARY KEY (`no`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 向账户表中插入测试数据:
INSERT INTO `bank`.`account`(`name`,`money`)
VALUES ('zlm',9999.00),
('hlw',7777.00);
模拟过程:
-- 设置提交状态为手动提交。
SET autocommit = 0;
-- 事务开启点。
START TRANSACTION;
-- hlw转出1111元给zlm。
UPDATE `bank`.`account` AS a SET a.`money` = a.`money`-1111 WHERE a.`name` = 'hlw';
-- zlm得到hlw转出的1111元。
UPDATE `bank`.`account` AS a SET a.`money` = a.`money`+1111 WHERE a.`name` = 'zlm';
-- 提交事务。
COMMIT;
-- 回滚事务。
ROLLBACK;
-- 事务完成(设置提交状态为自动提交)。
SET autocommit = 1;
2021.1.26
本文章是本人学习笔记,不进行任何商用所以不支持转载请理解,也请别拿去商用!
如果觉得对你有帮助那么欢迎你随时来回顾!
只为记录本人学习历程。
毕