SQL-事务与并发问题

        在数据库管理系统中,事务是一个重要的概念,它确保了一组数据库操作要么全部成功,要么全部失败,从而维护数据的完整性和一致性。随着多个用户同时访问数据库,事务的并发处理变得尤为重要。

1. 事务的定义

事务是指一组数据库操作,这些操作被视为一个单一的逻辑单元。事务的主要目标是确保数据在并发环境下的完整性和一致性。事务的四大特性被称为ACID特性:

  • 原子性 (Atomicity):事务中的所有操作要么全部成功,要么全部失败。如果事务中的任何操作失败,整个事务将被回滚。
  • 一致性 (Consistency):事务必须使数据库从一个一致性状态转换到另一个一致性状态。即使在发生错误或系统崩溃的情况下,数据库也必须保持一致性。
  • 隔离性 (Isolation):多个并发事务的执行互不干扰,每个事务的执行结果在提交之前对其他事务是不可见的。
  • 持久性 (Durability):一旦事务被提交,其结果是永久性的,即使系统崩溃也不会丢失。

2. 数据准备

        接下来,我们将通过一个简单的转账示例来演示事务的使用。首先,我们创建一个客户表并插入一些初始数据。

create table account (id int auto_increment primary key comment '主键id',name varchar(10) comment '姓名',money int comment '余额'
) comment '客户表';insert into account (id, name, money) values 
(null, '张三', 2000),
(null, '李四', 2000);

3. 转账操作示例

        在这个示例中,我们将实现张三向李四转账1000元的操作。我们将使用事务来确保转账的原子性。

3.1 查看自动提交状态

在进行事务操作之前,我们可以查看当前的自动提交状态:

select @@autocommit;  -- 查看当前事务自动提交状态,默认为1

3.2 开始事务

我们将手动控制事务的开始和结束:

start transaction;  -- 开始事务

3.3 执行转账操作

1.查询张三的余额:

select money from account where name = '张三';  -- 查询张三的余额

2.扣款操作:

update account set money = money - 1000 where name = '张三' and money >= 1000;  -- 扣款1000

 3.增加李四余额:

update account set money = money + 1000 where name = '李四';  -- 李四余额增加1000

3.4 提交或回滚事务

最后,我们需要提交事务以保存更改,或者在出现错误时回滚事务:

commit;  -- 提交事务
-- rollback;  -- 如果发生错误,回滚事务

4.脏读,不可重复读,幻读

1.脏读是指一个事务可以读取另一个事务未提交的修改。这可能导致读取到不一致的数据。

比如事务B读取了事务A尚未提交的数据

2.不可重复读是指在同一个事务中,多次读取同一数据的结果可能不同。这通常发生在一个事务读取数据后,另一个事务对该数据进行了修改。

比如事务A两次读取结果不一致,因为事务B对同一id提交了数据

3.幻读是指在一个事务中,读取到的结果集在同一事务内的后续查询中发生变化。这通常发生在一个事务读取了一组数据,而另一个事务插入了新数据。

比如事务A查询时没有数据,插入数据时却发现已经有数据存在了,导致插入数据失败

 

 5. 事务的隔离级别

        在并发环境中,多个事务可能会同时访问相同的数据,导致数据不一致的问题。SQL提供了四种事务隔离级别来控制这种并发访问的行为:

  • 读未提交 (Read Uncommitted):一个事务可以读取另一个事务未提交的修改。这可能导致“脏读”现象。
  • 读提交 (Read Committed):一个事务只能读取已提交的修改。这样可以避免脏读,但可能会导致“不可重复读”现象。
  • 可重复读 (Repeatable Read):在一个事务内,多次读取同一数据的结果是相同的。可以避免脏读和不可重复读,但可能会导致“幻读”现象。
  • 串行化 (Serializable):最高的隔离级别,所有事务串行执行,完全避免并发问题,但性能较低。

MySQL中默认是 Repeatable Read,而在 Oracle中默认是Read Committed

 

5.1 查看和设置事务隔离级别

我们可以通过以下SQL语句查看和设置当前会话的事务隔离级别:

示例:

select @@transaction_isolation;  -- 查看当前事务隔离级别set session transaction isolation level read committed;  -- 设置当前会话的事务隔离级别为读提交
set global transaction isolation level repeatable read;  -- 设置全局事务隔离级别为可重复读

6. 并发问题示例

为了更好地理解事务的并发问题,我们可以考虑以下场景:

6.1 脏读示例

-- 事务A
start transaction;
update account set money = money - 1000 where name = '张三';-- 事务B
start transaction;
select money from account where name = '张三';  -- 读取到未提交的值

在这个例子中,事务B在事务A提交之前读取了张三的余额,可能会导致事务B看到的余额不准确。

6.2 不可重复读示例

-- 事务A
start transaction;
select money from account where name = '张三';  -- 第一次读取-- 事务B
start transaction;
update account set money = money - 500 where name = '张三';  -- 更新张三的余额
commit;-- 事务A
select money from account where name = '张三';  -- 第二次读取,结果可能不同

        在这个例子中,事务A在第一次读取后,事务B对张三的余额进行了更新,导致事务A在第二次读取时看到的结果与第一次不同。

6.3 幻读示例

-- 事务A
start transaction;
select * from account where money > 1000;  -- 第一次读取-- 事务B
start transaction;
insert into account (name, money) values ('王五', 1500);  -- 插入新记录
commit;-- 事务A
select * from account where money > 1000;  -- 第二次读取,结果集可能不同

        在这个例子中,事务A在第一次查询时只返回了张三和李四的记录,但在事务B插入新记录后,事务A在第二次查询时可能会看到新的记录。

7. 总结

        事务是确保数据库操作一致性和完整性的关键机制。在并发环境中,事务的隔离级别能够有效控制并发访问带来的数据不一致问题。理解事务的ACID特性和不同的隔离级别将有助于开发者设计出更可靠的数据库应用。希望这篇文章能对你有所帮助。

最后点赞支持一下吧,好让我有继续创作的动力

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

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

相关文章

AI 代理参考架构

LLM Agent部署框架 围绕 ChatGPT 的讨论,现在已经演变为AI 代理。 图:AI代理平台参考架构 比尔盖茨最近设想(CNBC 采访:链接)未来我们将拥有一个能够处理和响应自然语言并完成许多不同任务的AI 代理。盖茨以计划旅行…

ETAS工具链自动化实战指南<一>

----自动化不仅是一种技术,更是一种思维方式,它将帮助我们在快节奏的工作环境中保持领先! 目录 往期推荐 场景一:SWC 之间 port自动连接 命令示例 参数说明 场景二:SWC与ECU 自动映射 命令示例 参数说明 场景三&…

c#实现数据导出为PDF的方式

PdfSharp vs iTextSharp: C#中PDF导出功能比较 PdfSharp 优点 轻量级:适合简单的PDF生成任务易于学习:API相对简单,学习曲线较缓开源:提供开源版本,可自由使用和修改纯C#实现:不依赖外部库或COM组件支持…

对零基础想转行网络安全同学的一点建议

最近有同学在后台留言,0基础怎么学网络安全?0基础可以转行做网络安全吗?以前也碰到过类似的问题,想了想,今天简单写一下。 我的回答是先了解,再入行。 具体怎么做呢? 首先,你要确…

1.初识redis

文章目录 1.认识redis1.1 mysql和redis 对比1.2分布式系统1.2.1单机架构与分布式架构1.2.2数据库分离(应用服务器和存储服务器分离)与负载均衡1.2.3负载均衡器1.2.4 数据库读写分离1.2.5 数据库服务器引入缓存1.2.6数据库分库分表1.2.7 引入微服务 2.常见概念解释2.1 应用(Appl…

音频导出后为什么效果变差了 FL Studio音频导出设置推荐

FL Studio是一款功能强大的编曲软件,除了可以编曲之外,FL Studio还支持各种音频格式导出。有的小伙伴在使用FL Studio导出音频后,会发现的导出的音频效果不理想,这很大的原因可能是导出设置不对造成的。下面给大家详细讲解&#x…

全面解析Gerapy分布式部署:从环境搭建到定时任务,避开Crawlab的坑

Gerapy分布式部署 搭建远程服务器的环境 装好带docker服务的系统 Docker:容器可生成镜像,也可拉去镜像生成容器 示例:将一个环境打包上传到云端(远程服务器),其他8个服务器需要这个环境直接向云端拉取镜像生成容器,进而使用该环境,比如有MYS…

代码块分类

局部代码块 public class Test {public static void main(String[] args) {{int a 10;}// 执行到此处时候,变量a已经从内存中消失了。 // System.out.println(a);} } 构造代码块 public class Test {private String name;private int age;{// 构造代码块System.out.…

GEC6818开发板的学习

1、开发板的简介 首先连接 开发板与电脑,需电脑安装串口驱动:例CH340 2、开发板的特性: 像素:800*480Pix分辨率:高,宽两个维度的像素点数目开发板色深为32位一个像素点占4个字节:分别为灰度保留位、RGB三原色各占一位3、为什么要内存映射 虽然LCD设备本质上也可以看作…

R语言:如何安装包“linkET”

自己在R语言中安装包“linkET”时报错不存在叫‘linket’这个名字的程辑包 尝试了install.packages("linkET")和BiocManager::install("linkET")两种安装办法都不行 >install.packages("linkET") WARNING: Rtools is required to build R pa…

【Java】对象与toString()方法

1.前言 了解toString之前,要先明白Object类是什么,Object是所有对象的父类。在Object类当中含有toString()方法,因此所有的对象也都包含有一个toString()方法。 2.toString 2.1 方法调用 toString()方法主要的作用,是对类与对象的…

错误信息“缺少msvcr120.dll”或“找不到msvcr120.dll”应该如何修复?几种方法快速修复

由于这个msvcr120.dll文件与应用程序的运行密切相关,任何与之相关的问题都可能导致应用程序无法正常运行。错误信息如“缺少msvcr120.dll”或“找不到msvcr120.dll”,通常出现在软件安装不正确或系统更新后。接下俩就教大家几种方法快速修复msvcr120.dll…

CentOS 7 安装流程详细教程

目录 前言1. CentOS 7 概述2. 安装环境准备2.1 硬件要求2.2 安装介质准备 3. CentOS 7 安装步骤3.1 引导安装程序3.2 选择语言和键盘布局3.3 配置安装源和软件包3.4 配置分区3.5 设置网络和主机名3.6 设置时间和日期3.7 设置 root 密码和创建用户3.8 开始安装并完成配置 4. 安装…

Cocos Creator2D游戏开发(14)---CocosCreator常用组件详解

Canvas RenderRoot2D 组件所在的节点是 2D 渲染组件数据收集的入口,而 Canvas(画布) 组件继承自 RenderRoot2D 组件,所以 Canvas 组件也是数据收集入口。所有 2D 渲染元素都必须作为 RenderRoot2D 的子节点才能被渲染。 Canvas还作为屏幕适配…

用基础项目来理解spring的作用

简介 spring官方的解释过于专业化,初学者可能比较难懂,接下来我将通过一个最基础的Java项目来尽可能的展示spring中的作用及spring的底层是如何来实现的。 项目结构 该项目是一个简单的JavaSE项目,没有maven或者tomcat等其他。只在控制台进…

《黑神话悟空》2024官方配置要求一览

黑神话悟空配置要求 1080P 高画质推荐6650xt和4060以上的显卡高画质 全景光追推荐4060 2k 高画质推荐4060ti/7700x以上的显卡 高画质全景光追推荐4070 4K 高画质推荐4070s起步 高画质全景光追推存4080S 一、官方配置要求一览 1、最低配置: 需要 64 位处理器和操作系…

什么是逃逸分析

如何快速判断是否逃逸就看方法内new的对象实体是否能够被外部方法进行调用 什么是逃逸分析 在java虚拟机中,对象是在java堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是如果经过逃逸分析(escape an…

[HDCTF 2023]Welcome To HDCTF 2023

方法一:找个炸弹死掉,flag就出现 方法二:查看页面源码,发现底部assets/js/game.js 复制后访问看到jsfuck编码 复制到控制台查看flag

功能测试与自动化测试详解

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 什么是自动化测试? 自动化测试是指利用软件测试工具自动实现全部或部分测试,它是软件测试的一个重要组成 部分,能完成许多手工测试无法实…

【数据结构入门】二叉树之堆的实现

文章目录 前言一、树1.1 树的概念1.2 树的相关概念 二、二叉树2.1 二叉树的概念2.2 特殊的二叉树2.3 二叉树的性质 三、堆3.1 堆的概念3.2 堆的性质3.3 堆的存储3.4 堆的实现3.4.1 堆的初始化3.4.2 堆的销毁3.4.1 堆向上调整算法3.4.2 堆向下调整算法3.4.3 堆的创建3.4.4 堆的插…