数据库事务详解

news2024/9/23 13:28:25
  1. 概述

事务就是数据库为了保证数据的原子性,持久性,隔离性,一致性而提供的一套机制, 在同一事务中, 如果有多条sql执行, 事务可以确保执行的可靠性.

  1. 数据库事务的四大特性

一般来说, 事务是必须满足 4 个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

1.原子性

一个事务中的所有操作, 要么全都执行, 要么全都不执行, 事务如果在执行过程中发生错误, 会回滚到事务开始执行前的状态.

2.持久性

事务处理结束后, 对数据的修改是永久的, 系统故障也不会丢失

3.隔离性

多个并发事务在同时对数据进行读写操作时, 隔离性可以防止多个事务并发执行时导致的数据不一致的问题, 事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)

4.一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据必须完全符合所有的预设规则, 前三个事务的特性都是为了保证事务的一致性.

  1. 事务的一些设置

默认情况下, mysql启动的是自动提交事务模式(变量 autocommit 为 ON),只要你执行 DML 操作的语句,MySQL 会立即隐式提交事务.

mysql处理事务的两种方法:

1.用 BEGIN, ROLLBACK, COMMIT 来实现

BEGIN; / START TRANSACTION; 开始一个事务

ROLLBACK 事务回滚

COMMIT 事务确认

2. 直接用 SET 来改变 MySQL 的自动提交模式:

SET GLOBAL autocommit=0; 禁止自动提交

SET GLOBAL autocommit=1;开启自动提交

3.查看 autocommit 模式

SHOW GLOBAL VARIABLES LIKE 'autocommit';

  1. 事务的隔离级别

为什么要有隔离级别?

MySQL 是一个服务器/客户端架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接上之后,就可以称之为一个会话。我们可以同时在不同的会话里输入各种语句,这些语句可以作为事务的一部分进行处理。不同的会话可以同时发送请求,也就是说服务器可能同时在处理多个事务,这样子就会导致不同的事务可能同时访问到相同的记录。我们前边说过事务有一个特性称之为隔离性,理论上在某个事务对某个数据进行访问时,其他事务应该进行排队,当该事务提交之后,其他事务才可以继续访问这个数据。但是这样子的话对性能影响太大,所以设计数据库的大叔提出了各种隔离级别,来最大限度的提升系统并发处理事务的能力, 只有 InnoDB 支持事务,所以这里说的事务隔离级别是指 InnoDB 下的事务隔离级别.

1.查看隔离级别

SELECT @@global.transaction_isolation,@@transaction_isolation;

mysql默认的隔离级别是可重复读

Mysql 数据提供四种不同级别的隔离级别,实际开发中可以根据不同的需要场景选择不同的隔离级别,除了串行级别以外其他级别都会存在某种问题.

2.设置隔离级别

设置全局隔离级别: SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

设置会话隔离级别: SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

(1)读未提交(read uncommitted)

一个事务读取到另一个事务未提交的修改, 会带来脏读, 不可重复读, 幻读的问题

第一个事务向表中插入了一条数据,但还未提交, 另一个事务就读到了表中插入的数据, 但第一个事务进行了回滚操作, 所以另一个事务读到的数据并不可靠, 读到了脏数据.

(2)读已提交(read committed)

一个事务只能读取另一个事务已经提交的修改, 避免了脏读的问题, 但还存在不可重复读, 幻读的问题

如果事务1向表中插入了一条数据但还未提交,事务2读取了一下数据,事务1再提交后, 事务2再次读取,读取到的数据不是之前读取到的数据, 这就出现了不可重复读的问题, 因为一个事务并不影响另一个事务, 所以一个事务中读到的数据始终应该是一致的.

(3)可重复读(repeatable read MySQL 默认隔离级别)

同一个事务中多次读取相同的数据结果始终是一样的, 避免了不可重复读, 但存在幻读的问题

正常情况下一般不会出现幻读的问题, 只有在执行select ... for update才会出现幻读, 幻读也就是一个事务中两次读到的结果不一致, 幻读和不可重复读相似, 两者的区别在于前者侧重于insert语句的情况, 后者侧重于update, delete的语句

(4)串行化(serializable)

事务串行执行可以避免以上所有问题, 原理就是加锁, 一个事务在执行的过程中, 另一个事务要等待前一个事务回滚或者提交事务从而释放锁, 但性能不好

  1. 事务的实现原理

MySQL 的日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等,此外 InnoDB 存储引擎还提供了两种事务日志:redolog(重做日志)和undolog(回滚日志)。其中 redolog 用于保证事务持性;undolog 则是事务原子性和隔离性实现的基础。

原子性实现

实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的 sql 语句。

InnoDB 实现回滚,靠的是 undo log:当事务对数据库进行修改时,InnoDB会生成对应的 undo log;如果事务执行失败或调用了 rollback,导致事务需要回滚,便可以利用 undo log 中的信息将数据回滚到修改之前的样子。

undo log 属于逻辑日志,它记录的是 sql 执行相关的信息。当发生回滚时,InnoDB 会根据 undo log 的内容做与之前相反的工作:对于每个 insert,回滚时会执行 delete;对于每个 delete,回滚时会执行 insert;对于每个 update,回滚时会执行一个相反的 update,把数据改回去

持久性实现

redo log 叫做重做日志,是保证事务持久性的重要机制。当 mysql 服务器意外崩溃或者宕机后,保证已经提交的事务,确定持久化到磁盘中的一种措施。innodb 是以页为单位来管理存储空间的,任何的增删改差操作最终都会操作完整的一个页,会将整个页加载到 buffer pool 中,然后对需要修改的记录进行修改,修改完毕不会立即刷新到磁盘,而且仅仅修改了一条记录,刷新一个完整的数据页的话过于浪费了。但是如果不立即刷新的话,数据此时还在内存中,如果此时发生系统崩溃最终数据会丢失的,因此权衡利弊,引入了 redo log,也就是说,修改完后,不立即刷新,而是记录一条日志,日志内容就是记录哪个页面,多少偏移量,什么数据发生了什么变更。这样即使系统崩溃,再恢复后,也可以根据 redo 日志进行数据恢复。另外,redo log 是循环写入固定的文件,是顺序写入磁盘的.

  1. 隔离级别实现原理(MVCC)

MVCC(多版本并发控制 Multi-Version Concurrent Control),是MySQL 提高性能的一种方式,配合 Undo log 和版本链,让不同事务的读-写、写-读操作可以并发执行,从而提升系统性能。

MVCC 使得数据库读不会对数据加锁,普通的 SELECT 请求不会加锁,提 高 了 数 据 库 的 并 发 处 理 能 力 。 借 助 MVCC , 数 据 库 可 以 实 现 READCOMMITTED,REPEATABLE READ 等隔离级别

InnoDB 的 MVCC 是通过在每行记录后面保存两个隐藏的列来实现的。一个保存了行的事务 ID(TRX_ID),一个保存了行的回滚指针(ROLL_PT)。

trx_id:每次对某记录进行改动时,都会把对应的事务 id 赋值给 trx_id隐藏列。

roll_pt:每次对记录进行改动时,都会把旧的版本写入到 undo 日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。

对该记录每次更新后,都会将旧值放到一条 undolog 中,就算是该记录的一个旧版本,随着更新次数的增多,所有的版本都会被 roll_pt 属性连接成一个链表,我们把这个链表称之为版本链,版本链的头节点就是当前记录最新的值。另外,每个版本中还包含生成该版本时对应的事务 id,这个信息很重要。

  1. ReadView 是什么

ReadView 是“快照读”SQL 执行时 MVCC 提取数据的依据

读已提交级别: 称为当前读,当每个事物每次读取时,会生成一个 readVew,读取的是最新数据.

可重复读级别: 称为快照读,当一个事务第一次查询时,会生成一个 readView,第二次查询时仍会从当前 readView 中读数据

  1. 锁机制

概述

首先来看两个事务的写操作之间的相互影响。隔离性要求同一时刻只能有一个事务对数据进行写操作,

InnoDB 通过锁机制来保证这一点。锁机制的基本原理可以概括为:事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。

按照粒度,锁可以分为表锁、行锁以及其他位于二者之间的间隙锁。表锁在操作数据时会锁定整张表,并发性能较差;行锁则只锁定需要操作的数据,并发性能好。但是由于加锁本身需要消耗资源(获得锁、检查锁、释放锁等都需要消耗资源),因此在锁定数据较多情况下使用表锁可以节省大量资源。MySQL中不同的存储引擎支持的锁是不一样的,例如 MyIsam 只支持表锁,而 InnoDB同时支持表锁和行锁,且出于性能考虑,绝大多数情况下使用的都是行锁。

1.行锁

行级锁是 Mysql 中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。

特点:

开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

2.间隙锁

锁的是一个区间,当我们用范围条件而不是相等条件检索数据,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙",InnoDB 也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key 锁)

3.表锁

表级锁是 MySQL 中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。最常使用的MYISAM 与 INNODB 都支持表级锁定。表级锁定分为表共享锁与表排他锁。

特点:

开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低

共享锁(S):又称读锁。允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。若事务 T 对数据对象 A 加上 S 锁,则事务 T 可以读 A 但不能修改A,其他事务只能再对 A 加 S 锁,而不能加 X锁,直到 T 释放 A 上的 S 锁。这保证了其他事务可以读 A,但在 T 释放 A 上的 S 锁之前不能对 A 做任何修改。

排他锁(X):又称写锁。允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。若事务 T 对数据对象 A 加上 X 锁,事务 T可以读 A 也可以修改 A,其他事务不能再对 A 加任何锁,直到 T 释放 A 上的锁。update,delete,insert 都会自动给涉及到的数据加上排他锁,

select 语句默认不会加任何锁类型,如果加排他锁可以使用 select …for update 语句,加共享锁可以使用 select … lock in share mode 语句。

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

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

相关文章

vscode ssh一直卡在wget的解决方案

vscode ssh一直卡在wget的解决方案找到commit_id 在服务器下点进该目录 .vscode-server\bin 一般日期最新的那一串就是我们需要的commit_id下载vscode-server-linux-x64.tar https://update.code.visualstudio.com/commit:${commit_id}/server-linux-x64/stable 将加粗部分替换…

2023年天津财经大学珠江学院专升本专业课考试题型

天津财经大学珠江学院关于2023年高职升本科专业课考试时间及题型一、专业课考试 (一)时间安排 2023年天津财经大学珠江学院高职升本科专业课考试定于2023年3月25日14:00-17:00进行,凡报考工商管理、旅游管理、税收学专业的考生&am…

智慧监所三维综合管控平台 构建数字智慧监管体系

建设背景监狱肩负着戒治管理、维持监所安全稳定等职责,目前全国有监管场所5500多个,监狱680多个。近年来,司法部不断加大司法行政改革力度,持续推进“数字法治,智慧司法”信息化体系建设战略部署。“智慧监狱”管理应用…

变更数据捕获(CDC)

从广泛意义上说,全球许多企业每天都需要通过频繁的数据批量处理与加载,来定期将数据从一个数据库迁移到另一个数据库(或数据仓库)。这类定期批量加载的工作,往往既耗费时间,又会消耗原始系统的大量处理能力。因此,管理…

design\project\学习 OAuth 读书笔记(二)

OAuth(二) 原文链接:OAuth 2.0 tutorial | OAuth flows 本文假设您已经看过 OAuth(一) 目录OAuth(二)OpenId ConnectOAuth2:令牌自检(Token Introspection)…

Qt std :: bad_alloc

文章目录摘要问题出现原因第一种 请求内存多余系统可提供内存第二种 地址空间过于分散,无法满足大块连续内存的请求第三种 堆管理数据结构损坏稍微总结下没想到还能更新参考关键字: std、 bad、 alloc、 OOM、 异常退出摘要 今天又是被BUG统治的一天&a…

fengMap 自定义dom 偏离实际位置;缩放时飘出地图所在区域

目录 一、问题 二、原因及解决方法 三、总结 一、问题 1.前人写了一份代码,很奇怪。使用 new fengmap.FMCompositeMarker添加的复合覆盖物位置是正常的,缩放的时候也是正常的,仍然处于地图内部;但是new fengmap.FMDomMarker添加…

Nginx 负载均衡服务失败场景

nginx可以配置负载均衡,我们可以通过配置实现nginx负载均衡。这里部署了两个服务producter-one和producter-one2。 upstream proxyproducter-one {server producter-one:8080 weight1;server producter-one2:8080 weight1;}# 访问其他服务server {listen 9090…

Netty学习(三):Netty线程模型

〇、前言网络编程的基本线程模型,详见:Netty学习(二):线程模型一、工作原理简图Netty主要基于主从 Reactors 多线程模型(如下图) 做了一定的改进,其中主从Reactor 多线程模型有多个R…

ServerSocket的构造方法

在开发TCP程序时,首先需要创建服务器端程序。JDK的java.net包中提供了一个ServerSocket娄,该类的实例对象可以实现一个服务器端的程序。通过查阅API文档可知,ServerSocket类提供了多个构造方法,接下来就对ServerSocket的构造方法进…

Pycharm配置QGIS环境

版本信息:QGIS: 3.22.16Pycharm:2022.3.2 (Community Edition)在QGIS官网下载安装包,下载稳定版本即可。配置步骤:安装完成后,使用Pycharm新建工程Python编译器选择之前配置好的编译器环境选择左侧第一个Vi…

YOLOv8训练自定义数据集(超详细)

借鉴 https://blog.csdn.net/qq_40716944/article/details/128648001一、准备训练环境安装 requirements.txt下载:https://raw.githubusercontent.com/ultralytics/ultralytics/main/requirements.txt然后在你 目录下执行pip install -r requirements.txt它的 requi…

【字符串】leetcode28. 实现 strStr()(C/C++/Java/Python/Js)

leetcode28. 实现 strStr() 1 题目2 KMP2.1 什么是KMP?2.2 KMP有什么用?2.3 什么是前缀表?2.4 最长公共前后缀2.5 为什么一定要用前缀表?2.6 如何计算前缀表2.7 前缀表与next数组2.8 使用next数组来匹配2.9…

2022 年度_职业项目总结_Java技术点归纳

Java技术点归纳目录概述需求:设计思路实现思路分析1.Structs 元工程改造2.个贷子系统开发3.架构的迭代开发,升级,部署,参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,fu…

学编程的 4 大阶段,你到哪了?

大家好,我是阅黑马学生无数的播妞……通过观察黑马学生的学习状态,播妞总结了他们来黑马后的四个学习状态,可以说,只要跨过这四个阶段,走向辉煌的编程人生就是必然的事情。阶段一:一窍不通这个阶段的学生&a…

2023初级会计详细学习计划打卡表!自律逆袭,一次上岸!

2023年初级会计职称考试报名时间:2月7日-28日考试时间:5月13日—17日给大家整理了《经济法基础》和《初级会计实务》两科超实用的学习打卡表重要程度、难易度、易错点、要求掌握内容、章节估分等都全部总结在一起,一目了然!为什么…

rk3288-android8-IR-mouse

IR问题: mouse按键使用不了 然后排查: 1.排查上报 ir_key6{ rockchip,usercode <0xbf00>;rockchip,key_table <0xff KEY_POWER>,<0xfe KEY_MUTE>, <0xfd KEY_1>, <0xfc KEY_2>, <0xfb KEY_3>, <0xfa KEY_4>, <0xf9 KEY_5>…

JavaEE进阶第六课:SpringBoot ⽇志⽂件

上篇文章介绍了SpringBoot配置文件&#xff0c;这篇文章我们将会介绍SpringBoot ⽇志⽂件 荔枝1.日志有什么用2.自定义日志输出2.1获取程序日志对象2.2使用相关方法输出日志2.3日志级别2.3.1日志级别的作用2.3.2日志级别如何设置2.4日志格式3.持久化日志4.更简单的日志输出4.1使…

【移动端表格组件】uniapp简单实现H5,小程序,APP多端兼容表格功能,复制即用,简单易懂【详细注释版本】

前言&#xff1a; 由于最近需要做移动端的项目 有个pc端的后台系统里面需要移一部分页面过来 而里面就有很多的表格&#xff0c;我就开始惯例网上先找前人栽的树&#xff0c;我好乘凉 然后找了一圈发现&#xff0c;不管是主流的移动端ui库或者网上自己写的帖子&#xff0c;或者…

224. 基本计算器

224. 基本计算器给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。注意:不允许使用任何将字符串作为数学表达式计算的内置函数&#xff0c;比如 eval() 。 示例 1&#xff1a;输入&#xff1a;s "1 1"输出&#xff1a;2示例 2&#…