当前位置:网站首页>【mysql篇-基础篇】事务
【mysql篇-基础篇】事务
2022-07-07 18:06:00 【我是不贪嘴吖】

简介
- 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求。这些操作要么全部成功,要么全部失败。
- 举例:
张三有2000,李四有2000,张三向李四转账1000。
- 步骤:查询张三账户余额,超过一千即可转账,张三账户减少1000,李四账户增加1000。
- 情况一:张三账户余额减少成功,李四账户余额增加成功。
- 情况二:张三账户余额减少成功,李四账户余额增加时抛了异常。这时就会出现金额错误。
- 解决:将三个步骤放在一个事务范围内。
开启事务—>查询张三账户余额—>张三余额减少1000—>李四余额增加1000—>抛异常—>回滚事务—>提交事务
- 操作:
- 建表语句:
CREATE TABLE account(
a_id INT AUTO_INCREMENT PRIMARY KEY COMMENT ‘主键ID’,
a_name VARCHAR(10) COMMENT ‘姓名’,
a_money INT COMMENT ‘账户余额’
)COMMENT ‘账户表’;
- 插入数据
INSERT INTO account(a_id,a_name,a_money) VALUES (NULL,‘张三’,2000),(NULL,‘李四’,2000);
- 更新数据
UPDATE account SET a_money=2000 WHERE a_name = ‘张三’ OR a_name =‘李四’;
1、转账操作:情况一(会出现账面不平衡,张三的账户余额减少了1000,但是李四的账号余额却没有加上1000)
(1)查询张三账户余额
SELECT * FROM account WHERE a_name = ‘张三’;
(2)将张三账户余额减去1000
UPDATE account SET a_money = a_money - 1000 WHERE a_name = ‘张三’;
抛出异常
(3)将李四账户余额加上1000
UPDATE account SET a_money = a_money + 1000 WHERE a_name = ‘李四’;
2、转账操作:情况二的方式一
(1)开启事务
A、查看提交方式语句:SELECT @@autocommit; 若为1,自动提交;若为0,手动提交。
B、设置提交方式为手动语句:SET @@autocommit = 0;
(2)查询张三账户余额
SELECT * FROM account WHERE a_name = ‘张三’;
(3)将张三账户余额减去1000
UPDATE account SET a_money = a_money - 1000 WHERE a_name = ‘张三’;
(4)将李四账户余额加上1000
UPDATE account SET a_money = a_money + 1000 WHERE a_name = ‘李四’;
(5)提交事务
COMMIT;
(6)回滚事务语句(如果在将李四余额加上1000之前报错,就可手动执行这条语句):
CALLBACK;
- 执行步骤和执行结果展示:
A、先将事务设置为手动提交;
B、执行(2)(3)(4);
C、然后再重新打开一个终端,执行语句select * from account;结果图片展示如下:
D、在执行(5),然后在新开的终端再重新执行下查询语句:select * from account;就会出现以下结果显示:
- 注意
- 如果在执行(4)之前,抛错了;则应去执行(6)
- SET @@autocommit与START TRANSACTION 或 BEGIN;都是手动提交方式;区别在于:
SET @@autocommit控制整个console,而START TRANSACTION控制的单个事务;
3、转账操作:情况二的方式二
(1)开启事务
A、查看提交方式语句:SELECT @@autocommit; 若为1,自动提交;若为0,手动提交。
B、设置提交方式为自动语句:SET @@autocommit = 1;
C、在一个终端执行语句: START TRANSACTION 或 BEGIN;
(2)查询张三账户余额
SELECT * FROM account WHERE a_name = ‘张三’;
(3)将张三账户余额减去1000
UPDATE account SET a_money = a_money - 1000 WHERE a_name = ‘张三’;
(4)将李四账户余额加上1000
UPDATE account SET a_money = a_money + 1000 WHERE a_name = ‘李四’;
(5)提交事务
COMMIT;
(6)回滚事务语句(如果在将李四余额加上1000之前报错,就可手动执行这条语句):
CALLBACK;
- 执行步骤和执行结果展示:
A 、设置为自动提交,执行START TRANSACTION;语句;
B、再执行(2)(3)(4);
C、再重新打开一个终端,执行select * from account;语句,结果如下:
D、如果在第一个终端执行了commit命令;则再另一个终端执行查询语句的时候,就会出现如下结果:
- 补充:
- 在执行插入语句的时候,数据库报错如下:
- 解决办法:
(1)通过语句查询表中字段的编码:SHOW FULL COLUMNS FROM 表名;
(2)执行修改语句:ALTER TABLE 表名 CONVERT TO CHARACTER SET gbk COLLATE gbk_chinese_ci;
(3)在对表字段的编码格式进行查询:(与第一句查询语句一样)
(4)对数据执行插入语句即可:
四大特性(ACID)
- 原子性(Atomicity)
- 事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency)
- 事务完成时,必须使所有的数据都保持一致的状态。
- 隔离性(Isolation)
- 数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability)
- 事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。(数据提交之后,就会永久的保存在磁盘)
并发事务问题
- 脏读
- 一个事务读到另一个事务还没提交的数据。
例如:事务A正在访问数据,并对数据进行了修改;此时事务B也来访问数据,使用了事务A更新之后的数据。
- 幻读
- 一个事务按照条件查询数据时,没有对应的数据行;但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影"。
例如:事务A根据条件查询数据,未查询到结果;此时并发事务B对数据进行插入并提交;事务A也对数据进行插入,但报错此数据已存在;事务A又对数据进行查询,还是访问不到数据。
- 不可重复读
- 一个事务先后读取同一条记录,但两次读取的数据不同,称为不可重复读。
例如:事务A对数据进行访问,此时并发事务B对数据进行了更新并提交;事务A再对数据进行访问时,就和前一次访问的数据不一致了。
四大隔离级别
- 读未提交(Read Uncommitted)
- 在这种隔离级别下,脏读、幻读、不可重复读都不能解决。
- 示例:
A、打开两个终端:终端1和终端2
B、终端1中执行SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
C、再执行START TRANSACTION ;
D、对数据进行查询:SELECT * FROM account;结果如下:
E、在终端2执行
START TRANSACTION ;
UPDATE account SET a_money = a_money - 1000 WHERE a_name = ‘张三’;
F、再次在终端1执行查询:SELECT * FROM account;结果如下:
- 读已提交(Read Committed)
- 在这种隔离级别下,解决了脏读。
- 示例:
A、打开两个终端:终端1和终端2
B、终端1中执行SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
C、再执行START TRANSACTION ;
D、对数据进行查询:SELECT * FROM account;结果如下:
E、在终端2执行
START TRANSACTION ;
UPDATE account SET a_money = a_money - 1000 WHERE a_name = ‘张三’;
F、再次在终端1指向查询:SELECT * FROM account;结果如下:
G、在终端2在进行事务的提交,执行commit;
H、再次在终端1进行查询:SELECT * FROM account;结果如下:
- 可重复读(Repeatable Read)(默认)
- 在这种隔离级别下,解决了脏读、不可重复读。
- 示例1:
A、打开两个终端:终端1和终端2
B、终端1中执行SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
C、再执行START TRANSACTION ;
D、对数据进行查询:SELECT * FROM account;结果如下:
E、在终端2执行
START TRANSACTION ;
UPDATE account SET a_money = a_money - 1000 WHERE a_name = ‘张三’;
commit;
F、再次在终端1指向查询:SELECT * FROM account;结果如下:
G、在终端1在进行事务的提交,执行commit;
H、再次在终端1进行查询:SELECT * FROM account;结果如下:- 示例2(会产生幻读):
A、在终端1执行
START TRANSACTION ;
SELECT * FROM account WHERE a_id = 3;结果如下:
B、在终端2执行:
START TRANSACTION ;
INSERT INTO account VALUES(3,‘王五’,2000);
COMMIT;
C、在终端1执行查询:SELECT * FROM account WHERE a_id = 3;结果如下:
D、在终端1执行INSERT INTO account VALUES(3,‘我也是王五’,2000);结果如下:
- 串行化(Serializable)
- 在这种隔离级别下,解决了脏读、幻读、不可重复读。
- 示例2:
A、打开两个终端:终端1和终端2
B、终端1中执行
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
START TRANSACTION ;
SELECT * FROM account WHERE a_id = 4;结果如下:
C、在终端2执行
START TRANSACTION ;
INSERT INTO account VALUES(4,‘麻子’,2000);
会发现一直在执行打转,最终会执行超时。
D、在终端1执行INSERT INTO account VALUES(4,‘麻子’,2000);则会执行成功:
- 查看事务的隔离级别:
- SELECT @@tx_isolation;
- mysql8之后查询语句:SELECT @@transaction_isolation;
- 设置事务隔离级别:(session对当前会话窗口有效;global对所有客户端的会话窗口有效)
- SET SESSION|GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
- 注意:
- 事务隔离级别越高,数据越安全,但是性能越低。
边栏推荐
- Interpretation of transpose convolution theory (input-output size analysis)
- CSDN syntax description
- R language ggplot2 visualization: use the ggqqplot function of ggpubr package to visualize the QQ graph (Quantitative quantitative plot)
- 开源重器!九章云极DataCanvas公司YLearn因果学习开源项目即将发布!
- Semantic slam source code analysis
- 机器学习笔记 - 使用Streamlit探索对象检测数据集
- R language ggplot2 visualization: use the ggviolin function of ggpubr package to visualize the violin diagram, set the palette parameter to customize the filling color of violin diagrams at different
- ASP. Net kindergarten chain management system source code
- Training IX basic configuration of network services
- The DBSCAN function of FPC package of R language performs density clustering analysis on data, checks the clustering labels of all samples, and the table function calculates the two-dimensional contin
猜你喜欢
openEuler 资源利用率提升之道 01:概论
8 CAS
论文解读(ValidUtil)《Rethinking the Setting of Semi-supervised Learning on Graphs》
Some important knowledge of MySQL
ASP.NET学习& asp‘s one word
模拟实现string类
编译器优化那些事儿(4):归纳变量
ASP. Net learning & ASP's one word
CIS芯片测试到底怎么测?
Is PMP beneficial to work? How to choose a reliable platform to make it easier to prepare for the exam!!!
随机推荐
Force buckle 674 Longest continuous increasing sequence
Mysql, sqlserver Oracle database connection mode
Some arrangements about oneself
一锅乱炖,npm、yarn cnpm常用命令合集
PMP practice once a day | don't get lost in the exam -7.7
IP tools
ASP.NET学习& asp‘s one word
Simulate the implementation of string class
School 1 of vulnhub
ASP. Net gymnasium integrated member management system source code, free sharing
Force buckle 1232 Dotted line
vulnhub之school 1
TS快速入门-泛型
CSDN语法说明
R language dplyr package mutate_ At function and min_ The rank function calculates the sorting sequence number value and ranking value of the specified data column in the dataframe, and assigns the ra
Yolov6:yolov6+win10--- train your own dataset
pom.xml 配置文件标签:dependencies 和 dependencyManagement 区别
mock.js从对象数组中任选数据返回一个数组
开源OA开发平台:合同管理使用手册
torch.nn.functional.pad(input, pad, mode=‘constant‘, value=None)记录