MySQL TCL 事务控制

文章目录

  • 1.事务四大特性
  • 2.事务并发问题
  • 3.事务隔离级别
  • 4.隔离级别查看与设置
  • 5.自动提交事务
    • 5.1 查看是否自动提交事务
    • 5.2 关闭或开启自动提交事务
  • 6.事务执行的基本流程
  • 7.设置事务的保存点
  • 参考文献

说到事务控制,先说一下数据库的事务是什么以及 MySQL 中我们必知的知识点。

1.事务四大特性

数据库事务(Database Transaction) ,是指对数据库的一系列操作组成的逻辑工作单元(Unit)。

并非任意的数据库操作序列都是数据库事务。数据库事务必须满足以下四个特性,习惯上被称之为 ACID 特性。

(1)原子性(Atomicity)

事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

(2)一致性(Consistency)

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。

(3)隔离性(Isolation)

多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

(4)持久性(Durability)

已被提交的事务对数据库的修改应该永久保存在数据库中。

MySQL 中并非所有的数据库存储引擎都支持事务操作,比如 MyISAM 就不支持。所以,使用事务处理的时候一定要确定所操作的表示是否支持事务处理,可以通过查看建表语句来查看有没有指定事务类型的存储引擎。当然,事务处理是为了保障表数据原子性、一致性、隔离性、持久性。这些都是要消耗系统资源,要谨慎选择。

本文以数据库引擎 InnoDB 为例来演示命令行模式下事务的基本操作。

2.事务并发问题

在数据库操作中,为了有效保证并发读取数据的正确性,提出了事务隔离级别。

数据库是要被广大客户共享访问的,那么在数据库并发操作过程中很可能会出现一些不确定的情况。

(1)更新丢失(Update Lost)

更新结果别其他事务覆盖。

两个事务同时读取相同数据并分别修改后,一个事务的修改覆盖了另一个事务的修改。这是因为系统没有执行任何锁操作,因此并发事务没有被隔离开来。

第一类更新丢失(回滚丢失)。

比如 A 事务对某一列 +1,B 事务对某一列 +2。B 事务事务提交后,A 事务进行了回滚,导致 B 事务的更新丢失。

第二类更新丢失(逻辑丢失)。

比如 A 事务对某一列 +1,B 事务对某一列 +2,A B 事务执行完成后正常预期结果应该是某一列的值被 +3,但是 B 事务的结果覆盖了 A 事务,导致结果只被 +2,A 事务的更新丢失了。

(2)脏读(Dirty Read)

读取未提交数据。

A 事务读取 B 事务尚未提交的数据,此时如果 B 事务发生错误并执行回滚操作,那么 A 事务读取到的数据就是脏数据。

(3)不可重复读(Non-repeatable Read)

前后多次读取,数据内容不一致。

A 事务在 B 事务开始前读和 B 事务结束后读的数据不一样,因为数据被事务 B 给修改了。

(4)幻读(Phantom Read)

一个行出现在查询结果集中,但不在较早查询的结果集中。

事务 A 在读取某个范围内的记录时,事务 B 在该范围内插入了新记录,事务 A 再次读取该范围内的记录时,会产生幻行。

幻读比不可重复读取更难防范,因为锁定第一个查询结果集中的所有行并不能阻止导致幻像出现的更改。

为了解决上面的问题,于是有了事务隔离。

3.事务隔离级别

MySQL 提供了多个事务隔离级别,每个隔离级别都有不同的特点和能力,以解决并发访问数据库时可能出现的不同问题。

以下是 MySQL InnoDB 支持的四个 SQL:1992 标准定义的四个隔离级别及其解决的问题。

  1. 读未提交(Read Uncommitted)

不允许第一类更新丢失,允许脏读、不可重复读、幻读和第二类更新丢失。

最低的隔离级别,事务可以读取其他事务尚未提交的数据,虽然拥有超高的并发处理能力及很低的系统开销,但很少用于实际应用,因为可能导致数据不一致性。

  1. 读已提交(Read Committed):

不允许第一类更新丢失和脏读。允许不可重复读、第二类更新丢失和幻读。

事务只能读取已经提交的数据,避免了脏读问题,但可能导致不可重复读和幻读。

这是大多数数据库系统的默认隔离级别,但不是 MySQL 默认。

  1. 可重复读(Repeatable Read):

不允许第一类更新丢失、脏读、不可重复读和第二类更新丢失,允许幻读。

事务在整个事务期间保持一致的快照,其他事务的修改不会影响正在运行的事务,从而防止不可重复读问题。

这是 MySQL 默认的事务隔离级别。

  1. 串行化(Serializable):

解决所有事务并发问题。

最高的隔离级别,通过强制事务排序,使之不可能相互冲突,从而解决防止所有并发问题。

在这个级别,可以解决上面提到的所有并发问题,但可能导致大量的超时现象和锁竞争。最直观的体现就是,当数据库隔离级别设置为串行化后,A事务在未提交之前,B事务对A事务数据的操作都会被阻塞。通常数据库不会用这个隔离级别,我们需要其他的机制来解决这些问题:比如乐观锁和悲观锁机制。

下面表格总结了事务并发问题和四大隔离级别的关系。

隔离级别第一类更新丢失脏读不可重复读第二类更新丢失幻读
读未提交x
读未提交xx
读未提交xxxx
读未提交xxxxx

每个隔离级别都在一定程度上解决了并发访问可能导致的问题,但随着隔离级别提升,对并发性能的影响也越大,因为更高级别的隔离通常需要更多的锁和资源开销。因此,在选择隔离级别时,您需要根据应用的需求平衡一致性和性能,选择最适合您应用场景的隔离级别。

4.隔离级别查看与设置

(1)查看全局和当前会话的事务隔离级别。

# 查看全局
SELECT @@global.transaction_isolation; # 查看当前会话
SELECT @@transaction_isolation;
SELECT @@session.transaction_isolation; 
SHOW VARIABLES LIKE 'transaction_isolation';

从 MySQL 8.0 起,tx_isolation 变量被 transaction_isolation 变量替换了,所以请使用最新的变量 transaction_isolation。

(2)更改事务的隔离级别。

MySQL 提供了 SET TRANSACTION 语句,该语句可以改变单个会话或全局的事务隔离级别。

SET [GLOBAL | SESSION] TRANSACTIONtransaction_characteristic [, transaction_characteristic] ...transaction_characteristic: {ISOLATION LEVEL level| access_mode
}level: {REPEATABLE READ| READ COMMITTED| READ UNCOMMITTED| SERIALIZABLE
}access_mode: {READ WRITE| READ ONLY
}

不显示指明 SESSION 或 GLOBAL,默认是 SESSION,即设置当前会话的事务隔离级别。如果使用 GLOBAL 关键字,为之后的所有新连接设置事务隔离级别,需要 SUPER 权限来做这个。

比如更改当前会话事务隔离级别为读已提交。

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;# 或省略 SESSION
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

也可以直接使用 SET 语句为变更系统变量 transaction_isolation 的值修改当前 session 的事务隔离级别。

SET transaction_isolation='READ-COMMITTED';

或者设置全局事务隔离级别为读已提交。

SET @@global.transaction_isolation='READ-COMMITTED';

5.自动提交事务

5.1 查看是否自动提交事务

MySQL 默认事务操作模式是自动提交模式(autocommit )。

系统变量 @@autocommit 用来控制一条SQL语句提交后是否自动执行,默认值是1,表示在mysql命令行模式下每条增删改语句在键入回车后,都会立即生效,而不需要手动commit。我们可以把它关闭,关闭之后需要commit,SQL语句才会真正生效。

由于系统变量 autocommit 分会话系统变量与全局系统变量,所以查询的时候,最好区别是会话系统变量还是全局系统变量。

查看当前会话是否处于自动提交模式。

SELECT @@autocommit;
SELECT @@session.autocommit;
SHOW SESSION VARIABLES LIKE 'autocommit';

如果返回结果为 1 或 ON,则表示当前会话处于自动提交模式;如果返回结果为 0 或 OFF,则表示当前会话未处于自动提交模式。

如果想查看全局配置,可查看系统变量 @@global.autocommit。

SELECT @@global.autocommit;
SHOW GLOBAL VARIABLES LIKE 'autocommit';

5.2 关闭或开启自动提交事务

  1. 关闭自动提交事务。

MySQL默认自动提交事务,即除非显式的开启事务(BEGIN 或 START TRANSACTION),否则每条 SOL 语句都会被当做一个单独的事务自动执行。但有些情况下,我们需要关闭事务自动提交来保证数据的一致性。

关闭自动提交事务主要有两种方法。一种是临时关闭,只对当前会话有效。第二种是永久关闭,对所有会话有效。

第一种:临时关闭。

关闭当前会话的自动提交事务。

SET autocommit = 0;
SET @@autocommit = 0;
SET @@session.autocommit = 0;
SET SESSION autocommit = 0;

这样之后,所有增删改语句,都必须使用 commit 之后,才能生效。

第二种:永久关闭。

在 MySQL 中,要永久地关闭自动提交事务,必须在配置文件中进行设置,以便在每次启动 MySQL 服务器时都保持这个设置。

找到 MySQL 的配置文件。在大多数情况下,MySQL 的配置文件名为 my.cnf 或 my.ini,具体位置取决于您的操作系统和安装方式。

打开配置文件并找到 [mysqld] 部分,添加或修改下面的配置项。

[mysqld]
init_connect='SET autocommit=0'

保存,然后重新启动 MySQL 服务器即可生效。

  1. 开启自动提交事务。

如果需要,可以开启自动提交模式。

SET autocommit = 1;
SET @@autocommit = 1;
SET @@session.autocommit = 1;
SET SESSION autocommit = 1;

要想永久有效,需要将上面配置文件中的配置项init_connect='SET autocommit=0'删除或设置为 1 即可。

6.事务执行的基本流程

首先创建一个测试数据表,建表语句如下:

CREATE TABLE transaction_test(id int primary key)engine=InnoDB;
  1. 开启一个事务。
BEGIN;
# 或
START TRANSACTION;
  1. 执行一系列增删改语句。
INSERT INTO transaction_test VALUES(1);
  1. 手动提交或回滚。

事务回滚:

ROLLBACK;

回滚后我们查看数据表中的数据。

SELECT * FROM transaction_test;
Empty set (0.00 sec)

表中没有数据,回滚成功。

手动提交事务:

COMMIT;

提交后,再 ROLLBACK 则不能回滚了,数据已经插入到数据表了。这里需要注意的是,在当前会话中,我们还没有手动 COMMIT 提交事务的时候,表中的数据已经被插入了,但对于其它会话,如果事务隔离级别是 READ COMMITED,那么在 COMMIT 之前,查询不到新插入的记录。

7.设置事务的保存点

在 MySQL 中,您可以使用事务保存点(Savepoint)来标记事务中的一个特定位置,以便在事务进行过程中进行部分回滚。事务保存点可以在事务内部创建,并且可以用于回滚到该保存点之前的状态,而不影响事务中的其他操作。

  1. 设置折返点
SAVEPOINT identifier;
  1. 回滚至折返点
ROLLBACK [WORK] TO [SAVEPOINT] identifier

这将撤销从保存点创建后到当前位置之间的所有操作。

  1. 提交或继续事务。

如果您满意回滚后的状态,可以继续进行其他操作,并最终提交事务。

COMMIT; -- 提交事务

通过使用事务保存点,您可以更细粒度地控制事务的回滚操作,以适应复杂的业务需求。请注意,保存点只在当前事务内部有效,并且一旦事务提交或回滚,保存点将被清除。


参考文献

13.3 Transactional and Locking Statements
MySQL 8.0 Reference Manual :: MySQL Glossary
15.7.2.1 Transaction Isolation Levels - MySQL
13.3.7 SET TRANSACTION Statement
MySQL 8.0 Reference Manual :: 5.1.8 Server System Variables
脏读、不可重复读、幻读、两类丢失更新与四大隔离级别 - 51cto

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/49377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ajax fetch Axios 的区别

AJAX:一种创建交互式网页应用的网页执行交互技术 通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。意味着:在不重新加载整个网页 的情况下,对网页某部分进行更新。 缺点: 针对MVC编程,…

YOLOv5+deepsort实现目标追踪。(附有各种错误解决办法)

一、YOLOv5算法相关配置 🐸这里如果是自己只想跑一跑YOLOV5的话,可以参考本章节。只想跑通YOLOv5+deepsort的看官移步到下一章节。 1.1 yolov5下载 🐸yolov5源码在github下载地址上或者Gitee上面都有。需要注意的是由于yolov5的代码库作者一直在维护,所以下载的时候需…

Log4j反序列化命令执行漏洞(CVE-2017-5645)Apache Log4j2 lookup JNDI 注入漏洞(CVE-2021-44228)

一.Log4j反序列化命令执行漏洞(CVE-2017-5645) Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码 环境:vulhub 工具下载地址&#xff1…

基于GRU门控循环网络的时间序列预测matlab仿真,对比LSTM网络

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 LSTM: GRU 2.算法运行软件版本 matlab2022a 3.部分核心程序 %构建GRU网络模型 layers [ ...sequenceInputLayer(N_feature)gruLayer(N_hidden)f…

【Hive】HQL Map 『CRUD | 相关函数』

文章目录 1. Map 增删改查1.1 声明 Map 数据类型1.2 增1.3 删1.4 改1.5 查 2. Map 相关函数2.1 单个Map 3. Map 与 String3.1 Map 转 string3.2 string 转 Map 1. Map 增删改查 1.1 声明 Map 数据类型 语法&#xff1a;map<基本数据类型, 基本数据类型> 注意是<>…

服务器中了Cylance勒索病毒,数据该怎么恢复?

近日&#xff0c;在市面上出现了一种名为Cylance的勒索病毒。经过云天数据恢复中心技术工程师对比分析后发现&#xff0c;该病毒不属于已知的任何勒索病毒家族中的成员&#xff0c;属于一种新型的勒索病毒&#xff0c;那接下来我们分析一下这种勒索病毒。 中了Cylance勒索病毒的…

主程技术分享: 游戏项目帧同步,状态同步如何选

网络游戏开发项目中帧同步,状态同步如何选&#xff1f; 网络游戏的核心技术之一就是玩家的网络同步,主流的网络同步有”帧同步”与”状态同步”。今天我们来分析一下这两种同步模式。同时教大家如何在自己的项目中采用最合适的同步方式。接下来从以下3个方面来阐述: 对啦&…

如何通过人工智能和自动化提高供应链弹性?

全球供应链中的数字化转型已经引起了广泛关注&#xff0c;尽管在过去的十年中&#xff0c;这一话题被广泛讨论&#xff0c;但许多公司仍然对如何实现这一不明确的目标感到困惑。人们普遍认识到这种转变的重要性&#xff0c;而新冠疫情及其带来的巨大影响也为行业向数字化转型方…

uniapp条形码实现

条形码在实际应用场景是经常可见的。 这里教大家如何集成uniapp条形码。条形码依赖类库JsBarcode. 下载JsBarcode源码&#xff0c;对CanvasRenderer进行了改进兼容uniapp。 import merge from "../help/merge.js"; import {calculateEncodingAttributes, getTotal…

【官方中文文档】Mybatis-Spring #使用 MyBatis API

使用 MyBatis API 使用 MyBatis-Spring&#xff0c;你可以继续直接使用 MyBatis 的 API。只需简单地使用 SqlSessionFactoryBean 在 Spring 中创建一个 SqlSessionFactory&#xff0c;然后按你的方式在代码中使用工厂即可。 public class UserDaoImpl implements UserDao {//…

韦东山老师 RTOS 入门课程(一)RTOS 介绍,熟悉裸机的汇编逻辑

韦东山老师 RTOS 入门课程 课程链接&#xff1a;韦东山直播公开课&#xff1a;RTOS实战项目之实现多任务系统 第1节&#xff1a;裸机程序框架和缺陷_哔哩哔哩_bilibili RTOS 介绍 裸机&#xff1a;固定顺序执行。 中断&#xff1a;可以一直专心做循环里的事情&#xff0c;直…

IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/

IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/ Idea下载官网一键直达&#xff1a; 官网一键直达

VuePress 数学公式支持

前言 博主在为 VuePress1.0 博客添加数学公式支持过程中遇到如下问题 问题一 在配置诸如 markdown-it-texmath,markdown-it-katex,markdown-it-mathjax3 这些插件后遇到 Error: Dynamic require of "XXX" is not supported 问题二 配置插件 vuepress-plugin-ma…

01、Cannot resolve MVC View ‘xxxxx前端页面‘

Cannot resolve MVC View ‘xxxxx前端页面’ 没有找到对应的mvc的前端页面。 代码&#xff1a;前端这里引入了 thymeleaf 模板 解决&#xff1a; 需要添加 thymeleaf 的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…

阿里云ECS服务器安装PostgreSQL

1. 概述 PostgreSQL是一个功能强大的开源数据库&#xff0c;它支持丰富的数据类型和自定义类型&#xff0c;其提供了丰富的接口&#xff0c;可以自行扩展其功能&#xff0c;支持使用流行的编程语言编写自定义函数 PostgreSQL数据库有如下优势&#xff1a; PostgreSQL数据库时…

【ThingJS | 3D可视化】开发框架,一站式数字孪生

博主&#xff1a;_LJaXi Or 東方幻想郷 专栏&#xff1a; 数字孪生 | 3D可视化框架 开发工具&#xff1a;ThingJS在线开发工具 ThingJs 低代码开发 ThingJs 低代码开发注意点场景效果配置层级层级常用API实例化 Thing&#xff0c;加载场景load 加载函数ThingJs 层级关系图查找层…

山西电力市场日前价格预测【2023-08-24】

日前价格预测 预测明日&#xff08;2023-08-24&#xff09;山西电力市场全天平均日前电价为319.98元/MWh。其中&#xff0c;最高日前电价为370.78元/MWh&#xff0c;预计出现在19: 30。最低日前电价为272.42元/MWh&#xff0c;预计出现在12: 45。 价差方向预测 1&#xff1a; 实…

港联证券|燃气板块午后走高,美能能源涨停,水发燃气大幅拉升

燃气板块21日午后快速拉升&#xff0c;到发稿&#xff0c;美能动力涨停&#xff0c;水发燃气涨超7%&#xff0c;蓝天燃气涨超5%&#xff0c;贵州燃气涨逾4%。 消息面上&#xff0c;受澳大利亚LNG工厂罢工忧虑影响&#xff0c;欧洲基准天然气价格一度大涨18%。 有报导称&#x…

记录:ubuntu20.04+ORB_SLAM2_with_pointcloud_map+ROS noetic

由于相机实时在线运行需要ROS&#xff0c;但Ubuntu22.04只支持ROS2&#xff0c;于是重装Ubuntu20.04。上一篇文章跑通的是官方版本的ORB_SLAM2&#xff0c;不支持点云显示。高翔修改版本支持RGB-D相机的点云显示功能。 高翔修改版本ORB_SLAM2&#xff1a;https://github.com/ga…

centos 7 安装 docker-compose curl 设置代理

sudo curl -x “http://192.168.1.2:3128” 需要验证的代理 sudo curl -x “http://username:password192.168.1.2:3128” 1.下载 sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/lo…