5、Mysql事务原理

news2024/11/25 0:50:12

脑图

一、概述

事务:一组操作要么全部成功,要么全部失败,目的是为了保证数据最终的一致性。
数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。
这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并发控制隔离机制、日志机制,用一整套机制来解决多事务并发问题

二、ACID

事务具有以下4个属性,通常简称为事务的ACID属性。
● 原子性(Atomicity) :当前事务的操作要么同时成功,要么同时失败。原子性由undo log日志来实现。
● 一致性(Consistent) :使用事务的最终目的,由其它3个特性以及业务代码正确逻辑来实现。
● 隔离性(Isolation) :在事务并发执行时,他们内部的操作不能互相干扰。隔离性由MySQL的各种锁以及MVCC机制来实现。
● 持久性(Durable) :一旦提交了事务,它对数据库的改变就应该是永久性的。持久性由redo log日志来实现

三、并发事务处理带来的问题

更新丢失(Lost Update)或脏写当两个或多个事务选择同一行数据修改,有可能发生更新丢失问题,即最后的更新覆盖了由其他事务所做的更新
脏读(Dirty Reads)事务A读取到了事务B已经修改但尚未提交的数据
不可重读(Non-Repeatable Reads)事务A内部的相同查询语句在不同时刻读出的结果不一致
幻读(Phantom Reads)事务A读取到了事务B提交的新增数据

四、事务隔离级别

脏读、不可重复读和幻读,都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。

隔离级别脏读(Dirty Read)不可重复读(NonRepeatable Read)幻读(Phantom Read)
读未提交(Read uncommitted)可能可能可能
读已提交(Read committed)不可能可能可能
可重复读(Repeatableread)不可能不可能可能
可串行化(Serializable)不可能不可能可能不可能

数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上“串行化”进行,这显然与“并发”是矛盾的。
不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读"和“幻读”并不敏感,可能更关心数据并发访问的能力。
查看当前数据库的事务隔离级别: show variables like ‘tx_isolation’;
设置事务隔离级别:set tx_isolation=‘REPEATABLE-READ’;
Mysql默认的事务隔离级别是可重复读(Oracle默认事务为读已提交),用Spring开发程序时,如果不设置隔离级别默认用Mysql设置的隔离级别,如果Spring设置了就用已经设置的隔离级别。

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

--当前会话隔离级别
select @@transaction_isolation;
--系统隔离级别
select @@global.transaction_isolation;
--MySQL 5.7.20前可以使用
set tx_isolation='read-uncommitted';
--MySQL 5.7.20后弃用tx_isolation
set session transaction isolation level read uncommitted;--设置读未提交
set session transaction isolation level read committed;--设置读已提交
set session transaction isolation level  repeatable read;--设置可重复读
set session transaction isolation level Serializable;--可串行化

事务隔离级别案例分析

表结构与数据

CREATE TABLE `account`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`balance` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `account` (`name`, `balance`) VALUES ('lilei', '450');
INSERT INTO `account` (`name`, `balance`) VALUES ('hanmei', '16000');
INSERT INTO `account` (`name`, `balance`) VALUES ('lucy', '2400');

读未提交(Read uncommitted)

打开两个窗口设置隔离级别为 读未提交(Read uncommitted)

select @@transaction_isolation;
set session transaction isolation level read uncommitted;
select  * from account;
update account a set a.balance=500 where a.id='1';

在这里插入图片描述

select @@transaction_isolation;
set session transaction isolation level read uncommitted;
select  * from account;

在这里插入图片描述
读未提交存在问题:
一旦客户端console_1的事务因为某种原因回滚,所有的操作都将会被撤销,那客户端console_2查询到的数据其实就是脏数据
注意:如果事务1修改lilei金额为500时候,没有提交事务。事务2这个时候去做查询,查询到金额为500,想要做增加50的业务逻辑,请使用

--请使用
update account a set a.balance=a.balance+50 where a.id='1';
--不能用
update account a set a.balance=550 where a.id='1';

这个操作来完成,如果直接设置balance为550,一旦事务1回滚必定造成脏数据,因为同时对id为1的数据进行修改是会加写锁的,使用balance+50情况下事务1回滚,这里的banlance就是450而不是500了。

读已提交(Read committed)

打开两个窗口设置隔离级别为 读已提交(Read committed)

select @@transaction_isolation;
set  session transaction isolation level read committed;
select  * from account;
update account a set a.balance=500 where a.id='1';

在这里插入图片描述

select @@transaction_isolation;
set  session transaction isolation level read committed;
--事务1未提交 450
select  * from account;
--事务1提交了 500
select  * from account;

在这里插入图片描述
读已提交存在问题:
在这里插入图片描述
同一个事务下面两次查询到的值不同,即产生了不可重复读的问题。

可重复读(Repeatableread)

可重复读隔离级别在事务开启的时候,第一次查询是查的数据库里已提交的最新数据,这时候全数据库会有一个快照(当然数据库并不是真正的生成了一个快照),在这个事务之后执行的查询操作都是查快照里的数据,别的事务不管怎么修改数据对当前这个事务的查询都没有影响,但是当前事务如果修改了某条数据,那当前事务之后查这条修改的数据就是被修改之后的值,但是查其它数据依然是从快照里查,不受影响。
打开两个窗口设置隔离级别为 可重复读(repeatable read)

set  session transaction isolation level repeatable read;
select @@transaction_isolation;
select  * from account;
update account a set a.balance=500 where a.id='1';

在这里插入图片描述

set  session transaction isolation level repeatable read;
select @@transaction_isolation;
--事务1未提交 450
select  * from account;
--事务1提交了 450 提交后真实为500
select  * from account;

在这里插入图片描述
这时候如果在事务2这里,进行lilie的balance+50,结果是550而不是500

update account a set a.balance=balance+50 where a.id='1';

在这里插入图片描述
可重复读的隔离级别下使用了MVCC(multi-version concurrency control)机制,select操作是快照读(历史版本);insert、update和delete是当前读(当前版本)

insert into account(name, balance) value ('zk',1000);

在这里插入图片描述

select @@transaction_isolation;
set  session transaction isolation level repeatable read;
#事务1未提交 插入一条数据
select  * from account;
#事务1提交了 还是未查询到新增数据
select  * from account;
update account a set a.balance=balance+50 where a.id=4;
select  * from account;

在这里插入图片描述
在这里插入图片描述

可串行化(Serializable)

打开两个窗口设置隔离级别为 串行化

select @@transaction_isolation;
set  session transaction isolation level serializable;
select  * from account a where a.id=1;

在这里插入图片描述

select @@transaction_isolation;
set  session transaction isolation level serializable;
--事务1未提交
update account a set a.balance=balance+50 where a.id=1;

在这里插入图片描述
说明在串行模式下innodb的查询也会被加上行锁,如果查询的记录不存在会给这条不存在的记录加上锁(这种是间隙锁)。
如果客户端1执行的是一个范围查询,那么该范围内的所有行包括每行记录所在的间隙区间范围都会被加锁。此时如果客户端2在该范围内插入数据都会被阻塞,所以就避免了幻读。
这种隔离级别并发性极低,开发中很少会用。

事务问题定位

--查询执行时间超过1秒的事务
SELECT
*
FROM
information_schema.innodb_trx
WHERE
TIME_TO_SEC( timediff( now( ), trx_started ) ) > 1;
--强制结束事务
--kill 事务对应的线程id(就是上面语句查出结果里的trx_mysql_thread_id字段的值)

在这里插入图片描述

五、大事务的影响

● 并发情况下,数据库连接池容易被撑爆
● 锁定太多的数据,造成大量的阻塞和锁超时
● 执行时间长,容易造成主从延迟
● 回滚所需要的时间比较长
● undo log膨胀
● 容易导致死锁

六、事务优化

● 将查询等数据准备操作放到事务外
● 事务中避免远程调用,远程调用要设置超时,防止事务等待时间太久
● 事务中避免一次性处理太多数据,可以拆分成多个事务分次处理
● 更新等涉及加锁的操作尽可能放在事务靠后的位置
● 能异步处理的尽量异步处理
● 应用侧(业务代码)保证数据一致性,非事务执行

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

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

相关文章

群辉助手Synology Assistant使用教程

下载 百度网盘链接直接下载即可 链接:https://pan.baidu.com/s/1XlQEcTCqBTsOgp-761jdOg?pwd5vyf 提取码:5vyf --来自百度网盘超级会员V5的分享 安装 直接双击安装,等待安装完成 能搜索到上图应用说明安装成功 使用 点击搜索按钮&…

浅谈餐饮业油烟在线监控系统的设计与研究

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要:现阶段餐饮行业发展十分迅速,为了更好地提升餐饮油烟的监控力度,强化餐饮业油烟在线监控系统的设计成为重中之重。油烟在线监控系统的强化可以降低油烟的排放量,同时在排烟的…

【赠书】算力经济概念提出者的倾力之作,深刻诠释超级计算的未来!

目录 1.内容简介2.读者受众3.图书目录 如果说蒸汽机是工业革命的引擎,发电机是电气时代的引擎,那么计算机就是数字信息时代的引擎,而超级计算机是引领科学计算创新、攀登新高峰的引擎。 现在,公有云的发展如火如荼,云…

八、云尚办公系统-管理端-审批设置

云尚办公系统:管理端-审批设置 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布,并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步!!…

Android处理内存泄漏

么是内存泄漏: 在Android开发过程中,当一个对象已经不需要再使用了,本该被回收时,而另个正在使用的对象持有它引用从而导致它不能被回收,这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产…

STM32外设系列—HC-05(蓝牙)

文章目录 一、蓝牙简介二、使用方法2.1 接线2.2 AT指令 三、蓝牙APP四、实战项目4.1 添加文件4.2 配置需要传递的参数4.3 获取返回值4.4 发送光照强度4.5 控制程序4.6 手机端页面设计4.6.1 新建调试工程4.6.2 设置通信变量4.6.3 编辑控件4.6.4 添加LED控制开关4.6.5 添加光照强…

Vue 时间转换

文章目录 将秒转换成简单时间格式方式一 表格渲染方式二 js转换 将时间转换为字符串方式一 年、月、日、时、分、秒、星期等信息方式二 返回多久之前的时间 将秒转换成简单时间格式 方式一 表格渲染 element-ui 表格为例&#xff0c;duration 单位为秒 <el-table-column …

Openresty原理概念篇(十一) 为什么要避免使用 NYI?

一 JIT编译器的死穴&#xff1a;为什么要避免使用 NYI ? ① 问题引入 1) 那么到底有哪些操作可以被 JIT,哪些不能呢?2) 怎样才可以避免写出不能被 JIT 的代码呢? ② 上节回顾 ③ 什么是 NYI&#xff1f; NYI函数 NYI完整的列表 ④ NYI列表中string库函数 说明&am…

sonarqube安装以及jenkins集成sonarqube

一、sonarqube安装 docker方式安装sonarqube docker 方式安装是最简便的&#xff0c;我选择了这个安装方式 1、下载镜像 docker pull postgres:latest docker pull sonarqube2、 创建挂载目录 #用于postgres的挂载目录 mkdir -p /opt/postgres/postgresql mkdir -p /opt/po…

慧博云通加入飞桨技术伙伴计划,共同推动企业AI应用创新

近日&#xff0c;慧博云通子公司慧博云通&#xff08;上海&#xff09;软件技术有限公司正式加入飞桨技术伙伴计划&#xff0c;双方将共同探索人工智能多场景创新应用&#xff0c;为企业提供智能化解决方案。 慧博云通 慧博云通科技股份有限公司&#xff08;股票代码&#x…

Pytorch分布式训练(一)

参考文献&#xff1a; 33、完整讲解PyTorch多GPU分布式训练代码编写_哔哩哔哩_bilibili pytorch进程间通信 - 文举的博客 (liwenju0.com) 前言 2023年&#xff0c;训练模型时&#xff0c;使用DDP&#xff08;DistributedDataParallel&#xff09;已经成为Pytorch炼丹师的标准…

sourcetree打开就闪退

1、问题分析 一直未出现如题描述情况&#xff0c;今早到公司可能是异常重启或者系统更新的愿意导致没有正常关机&#xff0c;出现了此种情况 2、问题解决 注&#xff1a;本文sourcetree安装在win11系统&#xff0c;win10等系统目录大同小异 ① (若快捷方式在桌面步骤①省略…

你的服务器还安全吗?用户数据是否面临泄露风险?

一系列严重的网络安全事件引起了广泛关注&#xff0c;多家知名公司的服务器遭到黑客挟持&#xff0c;用户的个人数据和敏感信息面临泄露的风险。这些事件揭示了网络安全的脆弱性和黑客攻击的威胁性&#xff0c;提醒着企业和个人加强对网络安全的重视。 一、入侵案例1.1 蔚来数据…

复习Javascript第二章

JavaScript 函数 JavaScript 函数是被设计为执行特定任务的代码块。 JavaScript 函数会在某代码调用它时被执行。 function myFunction(p1, p2) {return p1 * p2; // 该函数返回 p1 和 p2 的乘积 } JavaScript 函数语法 JavaScript 函数通过 function 关键词…

爆款视频生成器小程序源码搭建方案

爆款视频生成器是一种可以帮助用户快速制作出高质量视频的工具。它可以根据用户提供的素材、模板和音乐等要素&#xff0c;自动生成一个精美的视频。这种工具可以大大节省用户的时间和精力&#xff0c;同时还能够提高视频制作的效率和质量&#xff0c;使视频更易于被观众接受和…

开发一个商城小程序有哪些功能?

✔️近年来&#xff0c;随着微信小程序的不断优化和推出&#xff0c;越来越多的商家开始选择使用小程序作为销售渠道。商城小程序作为一种便捷、快速、高效的销售渠道&#xff0c;已经成为商家们打造线上商城的重要手段。商城小程序拥有着丰富的功能&#xff0c;可以满足不同商…

使用itextpdf填充表单域并生成pdf

文章目录 前言一、准备工作1.1 安装软件1.2 准备pdf1.3 设置表单域 二、创建项目三、编写代码3.1 编写工具类3.2 测试 四、测试结果 前言 最近手上有个任务&#xff0c;就是需要做一个pdf导出的功能。 可选择的技术点比较多&#xff0c;我这边综合考虑之后&#xff0c;使用的…

品牌推广的新路径:邀请歌手出席活动的独特策略“

在当今的市场竞争中&#xff0c;品牌推广和市场营销已经成为企业取得成功的重要因素之一。而邀请知名歌手出席活动则是一种备受瞩目的策略&#xff0c;可以为品牌带来巨大的优势和机遇。无论是与赵丽颖、迪丽热巴、张子枫、关晓彤、周冬雨还是孙俪等知名歌手合作&#xff0c;都…

WPF中Binding的数据转换—ValueConverters

WPF中Binding的数据转换—ValueConverters 在WPF中使用Binding经常会遇到需要转换的情况&#xff0c;如bool转为visibility&#xff0c;通常情况需要自己写一个类继承自IValueConverter接口&#xff0c;使用详情请参见Binding对数据的转换和校验&#xff0c;这种方法虽然不难&…

C 模拟包装机

一种自动包装机的结构如图 1 所示。首先机器中有 N 条轨道&#xff0c;放置了一些物品。轨道下面有一个筐。当某条轨道的按钮被按下时&#xff0c;活塞向左推动&#xff0c;将轨道尽头的一件物品推落筐中。当 0 号按钮被按下时&#xff0c;机械手将抓取筐顶部的一件物品&#x…