数据库中的事务,隔离级别,以及数据展示

news2024/11/18 6:02:42

 想要知道和学习数据库中的锁,要先学习数据库的事务和并发事务所带来的问题!

1.数据库中的事务!

1.1什么事务

 事务是由一组SQL语句组成的逻辑处理单元(多个sql进行修改,新增等),这些操作要么同时成功,要么全部回滚,在数据库中,事务是保证数据一致性和完整性得重要机制之一。

事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全部操作组成

 对于 MySQL 数据库来说,事务是指以执行start transaction命令开始,到执行commit或者rollback命令结束之间的全部 SQL 操作,如果这些 SQL 操作全部执行成功,则执行commit命令提交事务,表示事务执行成功;如果这些 SQL 操作中任一操作执行失败,则执行rollback命令回滚事务,表示事务执行失败,并将数据库回滚到执行start transaction命令之前的状态。特别地,在现阶段的 MySQL 数据库中,仅 InnoDB 和 NDB 两个存储引擎是支持事务的。

 以 MySQL 的 InnoDB 存储引擎为例,其默认是开启autocommit配置的,即自动提交事务。在自动提交模式下,如果没有以start transaction显式地开始一个事务,那么每条 SQL 语句都会被当做一个事务执行提交操作。通过set autocommit = 0命令可以关闭自动提交模式,如果关闭了autocommit,则所有的 SQL 语句都在一个事务中,直到执行commit或rollback,该事务结束,并同时开始另外一个新的事务。在此,需要我们注意的是,autocommit参数是针对连接的,在一个连接中修改了参数,不会对其他连接产生影响。

 注意:除此之外,在 MySQL 中,还存在一些特殊的命令,如果在事务中执行了这些命令,则会强制执行commit命令提交事务,如 DDL 语句(create table/drop table/alter table)、lock tables语句等。不过,我们常用的select、insert、update和delete命令,都不会强制提交事务。

1.2数据库事务的基本演示

演示:

常见的数据库事务操作命令:

  1. BEGIN - 用于开始一个事务。

  2. COMMIT - 用于提交事务。这将使所有已执行的更改永久保存到数据库中。

  3. ROLLBACK - 用于回滚事务。如果事务出现错误或需要取消,这将撤消已执行的所有更改。

  4. SAVEPOINT - 使用SAVEPOINT创建一个保存点,可以在回滚事务时使用它来恢复到该保存点。

  5. ROLLBACK TO SAVEPOINT - 恢复事务到指定的保存点。

  6. SET TRANSACTION - 用于控制事务的特性,例如隔离级别和读取模式。

  7. LOCK TABLE - 用于锁定表,以确保在事务期间没有其他用户对其进行更改。

  8. UNLOCK TABLE - 用于解锁表,以允许其他用户对其进行更改

 建表语句:


CREATE TABLE my_table (
  id INT PRIMARY KEY,
  name VARCHAR(50),
  birth_date DATE
);

 开启事务;回滚事务;这样该执行的语句就会全部执行失败!

BEGIN;
INSERT INTO my_table (name, birth_date) VALUES 
  ( 'hua444', '1990-07-01');

INSERT INTO my_table (name, birth_date) VALUES 
  ( 'hua44', '1990-07-01');
ROLLBACK ;

开启事务;提交事务;这样所有语句只要都是成功的就会全部执行成功!,有一条执行失败,就全部回滚!

 

 特别简单(执行失败情况)

一条SQL语句错误,全部回滚! 

SAVEPOINT 演示

用于创建一个保存点(savepoint)。使用 SAVEPOINT 可以在事务执行过程中创建保存点,并在后续操作中回滚到该保存点

当事务包含多个步骤时,可以使用 SAVEPOINT 将其分为更小的部分,并在每个步骤之间创建保存点。如果后续步骤出现错误,可以回滚到之前的保存点,避免取消整个事务。

 ROLLBACK TO SAVEPOINT 用于回滚到指定的保存点。使用 ROLLBACK TO SAVEPOINT 可以在事务执行过程中撤销已完成的操作,并返回到指定的保存点。

当事务包含多个步骤时,可以使用 SAVEPOINT 将其分为更小的部分,并在每个步骤之间创建保存点。如果后续步骤出现错误,可以使用 ROLLBACK TO SAVEPOINT 命令将事务恢复到之前的保存点,避免取消整个事务。

 使用 ROLLBACK TO SAVEPOINT 时,需要注意以下几点:

  1. 如果事务已经提交,则无法回滚到任何保存点

  2. 如果尝试回滚到一个不存在的保存点,则会导致错误。

  3. 回滚到保存点时,指定的保存点及其之后的操作都将被撤销。也就是说,如果回滚到某个保存点,那么该保存点以后的操作都将失效,并且不能再次提交。

因此,在使用 ROLLBACK TO SAVEPOINT 时,必须小心谨慎,确保正确地控制事务的执行和回滚。同时,在设计数据库事务时,也应该充分考虑到使用 SAVEPOINT 和 ROLLBACK TO SAVEPOINT 的情况,以便更好地管理数据的一致性和完整性。

1.3事务的四大特征!(ACID)

  • 原子性(Atomicity):事务的所有操作要么全部完成,要么全部回滚,不会出现只执行了部分操作的情况。
  • 一致性(Consistency)事务执行前后数据库的状态必须保持一致,即从一个一致性状态到另一个一致性状态。
  • 隔离性(Isolation):多个事务并发执行时,每个事务都应该感觉不到其他事务的存在。
  • 持久性(Durability):一旦事务提交,其所做的修改就应该永久保存在数据库中,即使出现系统故障或崩溃的情况也不应该影响数据的持久性。

1.4mysql并发事务出现的问题

多个并发事务可能会同时修改同一个数据集,从而导致一些问题。

  1. 脏读(Dirty Read) - 当一个事务正在向数据库写入数据时,另一个事务读取到了这个未提交的数据,导致读取到了不正确的数据。

  2. 不可重复读(Non-Repeatable Read) - 在一个事务中,多次读取同一行记录,但在事务执行期间,其他事务已修改或删除了该行记录,导致不同的结果。

  3. 幻读(Phantom Read) - 在一个事务中多次查询某个范围内的记录,但在事务执行期间,其他事务已经插入或删除了该范围内的记录,导致结果集合不一致。

  4. 更新丢失(Lost Update) - 当两个或更多的事务尝试同时更新同一行记录时,其中一个事务的更新可能会被覆盖或丢失。

 1.脏读

 A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个时候A事务立即读取了这个脏数据,但事务B良心发现,又用回滚把数据恢复成原来干净、纯粹的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读

 2.不可重复读(前后多次读取,数据内容不一致)

 事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读。

 同一个事务A读取到一条数据,但是同一条数据不一致,(事务b修改了)。

 幻读(前后多次读取,数据总量不一致)

事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。

幻读两种说法:

说法一:事务 A 根据条件查询得到了 N 条数据,但此时事务 B 删除或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候真实的数据集已经发生了变化,但是A却查询不出来这种变化,因此产生了幻读。

这一种说法强调幻读在于某一个范围内的数据行变多或者是变少了,侧重说明的是数据集不一样导致了产生了幻读。

说法二:幻读并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:A事务select 某记录是否存在,结果为不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。产生这样的原因是因为有另一个事务往表中插入了数据。

  • 幻读说的是存不存在的问题:原来不存在的,现在存在了,则是幻读
  • 不可重复读说的是变没变化的问题:原来是A,现在却变为了B,则为不可重复读

 1.5事务的隔离级别

读未提交(Read uncommitted),

读已提交(Read committed),

可重复读(Repeatable read),

可串行化(Serializable)

 1.读未提交(Read uncommitted

在这种隔离级别下,所有事务能够读取其他事务未提交的数据。读取其他事务未提交的数据,会造成脏读。因此在该种隔离级别下,不能解决脏读、不可重复读和幻读。

 2.读已提交(Read committed)

 在这种隔离级别下,所有事务只能读取其他事务已经提交的内容。能够彻底解决脏读的现象。但在这种隔离级别下,会出现一个事务的前后多次的查询中却返回了不同内容的数据的现象,也就是出现了不可重复读。

注意【1】这是大多数数据库系统默认的隔离级别,例如Oracle和SQL Server,但mysql不是。

 可重复读(Repeatable read)

 在这种隔离级别下,所有事务前后多次的读取到的数据内容是不变的。也就是某个事务在执行的过程中,不允许其他事务进行update操作,但允许其他事务进行add操作,造成某个事务前后多次读取到的数据总量不一致的现象,从而产生幻读。

mysql的默认事务隔离级别

 四、可串行化(serializable)

在这种隔离级别下,所有的事务顺序执行,所以他们之间不存在冲突,从而能有效地解决脏读、不可重复读和幻读的现象。

但是安全和效率不能兼得,这样事务隔离级别,会导致大量的操作超时和锁竞争,从而大大降低数据库的性能,一般不使用这样事务隔离级别。

 

 事务隔离级别演示:

注意:

1.建表的时候,选择 Innodb引擎才支持事务
2.默认情况下, MySQL 是自动提交事务, 每次执行一个 SQL 语句时, 如果执行成功, 就会向数据库自动提交,而不能回滚。 如果某一组操作需要在一个事务中, 那么需要使用 start transaction(或 begin), 一旦 rollback 或 commit 就结束当次事务, 之后的操作又自动提交。
3.如果需要在当前会话的整个过程中都取消自动提交事务, 进行手动提交事务, 就需要设置 set autocommit = false(或 set autocommit = 0),那样的话每一句 SQL 都需要手动 commit 提交才会真正生效。 rollback 或 commit 之前的所有操作都视为一个事务, 之后的操作视为另一个事务, 还需要手动提交或回滚。
4.和 Oracle 一样, DDL (数据定义语言)语句是不能回滚的, 并且部分的 DDL 语句会造成隐式的提交, 因此最好事务中不要涉及DDL 语句。

 语句:

开启一个事务:start transaction (begin)

提交事务:commit

回滚事务:rollback

查看全局事务隔离级别:SELECT @@global.tx_isolation;

设置全局事务隔离级别:set global transaction isolation level read committed(set global tx_isolation =‘read-committed’)

查看当前会话事务隔离级别:SELECT @@tx_isolation(show variables like ‘tx_isolation’)

设置当前会话事务隔离级别:set session transaction isolation level read committed(set tx_isolation =‘repeatable-read’)

查看mysql默认自动提交状态:select @@autocommit(show variables like ‘autocommit’)

设置mysql默认自动提交状态:set autocommit = 0(set autocommit = false;【不自动提交】)

演示:

开启两个客户端进行演示

(查看全局事务隔离级别)

(设置全局的隔离事务级别----全局会进行修改) 

 (会话1,设置当前的隔离模式为ru,会话2为默认rr)

 (全部设置成 ru 读未提交)

(查看mysql默认提交状态,并设置成手动提交) 

 

 上边只是简单的设置操作,下边展示隔离事务的操作

1.演示脏读  (一个事务可以读取另一个事务未提交的数据)(RU)

开启两个客户端,进行设置ru隔离级别(以上操作即可)

用my_tablle数据库 

 脏读演示

 这时会话2,还没有进行手动提交或回滚数据,也会出现不可重复读!

 2.(RC,读已提交演示)

设置当前会话为 rc

这个时候,就读不到会话一还未提交的数据!! 

 

 

rc的隔离级别解决了脏读问题,但是没有解决不可重复读;

  3.(RR,可重复读)mysql默认隔离级别

会话1已经提交,会话2查询了两遍,两条数据,避免了不可重复读。

 展示幻读现象

会话1,第一次没有读到数据 ,会话2直接插入数据并提交,会话1插入提交,到最后得到了两条数据。 

 可串行化自己试试吧!

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

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

相关文章

跟踪任何目标(想跟踪什么就跟踪什么)

结果展示 介绍 该项目是一个简单的跟踪工具,可以用于跟踪任何你感兴趣的东西。它提供了一个基于Web的界面,让用户可以轻松地创建和管理跟踪列表,同时也提供了一个RESTful API,可以方便地进行数据交互。 项目的原理是将用户需要跟踪的内容,通过创建跟踪项的方式存储到数据…

Hausdorff 距离

1. 定义 给定欧氏空间中的两点集 A { a 1 , a 2 , . . . } \rm A\left \{a_1, a_2,... \right\} A{a1​,a2​,...} 和 B { b 1 , b 2 , . . . } \rm B\left \{b_1, b_2,... \right\} B{b1​,b2​,...} , H a u s d o r f f {\rm Hausdorff} Hausdorff 距离就是用…

基于SSM的在线考试系统开发与设计-(附源码文档)-毕业设计

文章目录 1.适用人群2.你将收获3.项目介绍4.系统需求分析4.1 需求特性分析4.2 功能需求分析 5.系统设计5.1 系统总体结构设计5.2 数据库设计5.2.1 数据库概念原则设计5.2.2 数据库各部分模块设计5.2.3 数据库表设计 6.系统详细设计6.1 系统各模块功能设计6.1.1 登录模块6.1.2 注…

chatgpt赋能python:如何利用Python加快计算速度

如何利用Python加快计算速度 在大数据时代,计算效率的问题成为了企业和科研机构普遍关注的焦点问题。Python是一种高级编程语言,其具有灵活、易学、语法简洁、运行速度快等优点,因此在数据分析和科学计算领域广泛应用。然而,Pyth…

chatgpt赋能python:Python内部函数介绍

Python内部函数介绍 Python是一门功能强大、易于学习的编程语言,拥有许多内部函数可供使用。本文将介绍Python的内部函数和其用途,以便更好地利用和理解Python。 什么是内部函数? 内部函数是Python提供的一组内置函数,它们可以…

2023/5/25总结

学习CSS list-style:none 去掉无序列表的带有的样式,比如原点。 border-radius:length 设置圆角,也可以写%,不一定需要些半径大小,也可以顺时针写半径大小,就会出现四个顶点不一样的圆角。或者写:borde…

chatgpt赋能python:Python写Log的技巧与最佳实践

Python 写 Log 的技巧与最佳实践 在编写 Python 应用程序时,日志记录(Logging)是一项非常重要的功能,尤其是在调试或部署过程中。本文将介绍一些 Python 写 Log 的技巧和最佳实践,以帮助你更好地处理日志记录并提高应…

Java的String(字符串详解)

字符串 1.字符串的常见构造方法 主要有三种,一种是直接使用常量去构造,要么使用new String来构造,或者还可以使用字符数组的形式。 public static void main(String[] args) { // 使用常量串构造 String s1 "hello"; System.ou…

order by排序语句的用法

文章目录 学习连接语法用法示例1、按单个列的值排序2、按多个列的值排序3、按指定的规则排序4、按中文拼音字母顺序5、Order by和where条件共用 数据库中常用order by关键字对结果集进行排序,又可使用desc和asc来进行指定规则的排序。 学习连接 数据库:…

chatgpt赋能python:单行for循环:Python编程的神器

单行for循环:Python编程的神器 Python是一门功能强大的编程语言,其中的单行for循环功能更是让它的编程效率倍增。在本文中,我们将探讨单行for循环是如何提升编程效率的。 什么是单行for循环 单行for循环是一种简单而强大的编程方式。它可以…

【利用AI让知识体系化】V8引擎相关知识

文章目录 I. 引言V8引擎的背景和概述 II. V8的设计和工作原理V8的整体设计V8的工作流程和运行机制V8在浏览器中的应用场景 III. 内存管理内存模型和内存管理策略垃圾回收机制和算法内存泄漏和内存优化 IV. JIT编译器JIT编译器的作用和优势V8的编译流程和编译器类型编译器优化技…

make的路径搜索

文章目录 前言一、VPATH二、vpath三、vpath 与 VPATH 的差别四、GPATH 用法总结 前言 在大型软件项目中,通常会存在多个目录,包含有源代码、头文件、库文件等不同类型的文件。在编译或链接时,需要指定相应的文件路径才能正确地进行构建。但是…

【计算机图形学】曲线和曲面(Bezier曲线 Bezier曲面)

模块5 曲线和曲面 一 实验目的 编写曲线和曲面的算法 二 实验内容 1:绘制Bezier曲线,并采用自行设计输入和交互修改数据点的方式。 实验结果如下图所示: 第一步:输入特征多边形的顶点个数,并按照顺序输入顶点的坐…

css3新增特性

1. 初始化 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, …

怎么通过ecs云服务器来给小程序发送消息

如果您想通过 ECS 云服务器向小程序发送消息&#xff0c;可以使用 WebSocket 技术。具体步骤如下&#xff1a; 1. 在 ECS 云服务器上搭建 WebSocket 服务器。您可以使用 Node.js、Java、Python 等编程语言来实现 WebSocket 服务器&#xff0c;具体实现方式可参考相关技术文档或…

Java笔记——KMP算法

KMP算法 文章目录 KMP算法KMP算法介绍主要逻辑Next数组KMP搜索代码解释生成next数组模式串匹配 源码展示 KMP算法介绍 KMP算法是一种串的模式匹配算法&#xff0c;用来求子串在主串的位置。是数据结构中比较难的一种算法。KMP算法的核心在于点在于如何利用子串生成next数组&am…

vim的使用、vim入门的三种常用模式、以及vim中常用的命令(超详细)

vim 入门的三种常用模式&#xff1a;分别是 1. 命令模式、2. 插入/编辑模式、3. 底行模式 1. 命令模式 控制屏幕光标的移动&#xff0c;字符、字或行的删除&#xff0c;移动复制某区段及进入Insert mode下&#xff0c;或者到 last line mode 如下&#xff0c;这个就是命令模式…

Numpy入门看这一篇就够了【史上入门最简单,开袋即食】

一边学习一边分享&#xff0c;好记性不如烂笔头 目录 一边学习一边分享&#xff0c;好记性不如烂笔头 NumPy问题思考&#xff1a; numpy是什么&#xff1f; 为什么要学习numpy&#xff1f; numpy是怎么组成的&#xff1f;特点是什么&#xff1f; numpy的应用场景有哪些&a…

css定位模式

1. 为什么需要定位&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…

自动化专业求职方向与前景分析(合集)

自动化专业求职方向与前景分析 自动化专业求职方向 自动化专业是近几年高校教育改革中几个控制类专业合并后形成的宽口径专业&#xff0c;其实自动化就是搞控制的&#xff0c;用老师的话说就是控制一切可以控制的物理量&#xff0c;还说学自动化的人都要有控制的欲望。所谓控制…