百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Mysql-事务机制原理及初步优化(mysql事务的原理)

toyiye 2024-08-29 00:18 5 浏览 0 评论

引言

在之前的文章中,对explain用法以及利用mysql的索引,在实际项目中进行各种优化的方式。说完优化后,不得不提到mysql另一大块功能了,那就是事务。在实际开发中,可能有很多人对事务的感知度不高,可能就是在代码中写一个@Transaction,或者在oracle的plsql中,点一下解锁,然后修改完数据点一下提交[无辜笑]。具体mysql数据库有什么事务,或者在项目中是具体怎么应用的,估计一下说不完整。此文章就是针对mysql的各种事务以及其使用进行介绍。

事务的作用

事务主要是为了保证一组数据库操作执行后,整组操作只能一起成功,或者一起失败,保证数据一致性。通俗点也就是在银行取100块,从你账户扣100块和吐100块这两个操作必须一起成功或失败,否则可能就会出现你账户钱扣了,却没有拿到钱的尴尬情况。其实从官方文档上,事务有以下四个属性,也就是我们常挂嘴边的ACID:

  • 原子性:表示一个事务操作只能一起成功和一起失败,也即一个事务就是最细粒度的操作,不可再拆分。
  • 一致性:这个是事务要达到的最终效果,mysql事务也就是为了保持读取数据的一致性
  • 隔离性:当mysql存在多个事务并发操作时,保证事务的内部不互相干扰,MySQL是通过各种锁以及内部机制保证的。当然不同的事物隔离性是不一样的,这个是本文的重点。
  • 持久性:也即事务一旦提交,提交的数据是永久生效的,同时mysql会把数据写道redo log,来保证其持久性

并发事务带来的常见问题以及常见的事务隔离级别

在实际项目中,对数据库并发操作是很常见的,多个线程对一个表操作导致的死锁、脏写、脏读等都是我们问题,接下来先介绍这些问题,以及mysql四种事务隔离级别可能存在的事务问题。首先事务常见问题如下:

  • 脏写:多个事务之间,对数据库的修改出现了丢失或者被错误覆盖
  • 脏读:一个事务读取到另一个事务未commit的数据
  • 不可重复度:一个事务内,同一查询语句,多次查询结果不相同
  • 幻读:一个事务内,读取到其他事务新增提交的数据

接下来是mysql事务隔离级别:

  • 读未提交(read-uncommitted):可以读取到其他事务未提交的数据。可能出现脏读、不可重复读、幻读的问题。因为问题太多,所以也基本不会使用。
  • 读已提交(read-committed):简称RC,可以读取到其他事务已提交的数据。可能出现不可重复读、幻读的问题。一般在并发要求比较高的场景,使用此级别提高效率,不过得在java层面做做控制。
  • 可重复度(repeatable‐read):简称RR,保证一个事务内,同一查询语句,查询的结果相同。可能出现幻读问题。这也是mysql默认的一个事务隔离级别,做政府类型的项目,用这个级别基本够用。
  • 可串行化(serializable):事务隔离的最高级别,不会出现事务问题,不过这也会使得mysql性能降到最低,基本上表的并发操作会因为数据库变成串行等待。基本不会使用。

这里提一下,mysql默认设置的隔离级别是RR,利用@Transactional注解时,可以通过isolation设置spring的隔离级别,整体设置方式为 @Transactional(isolation = Isolation.READ_COMMITTED)。如果不设置隔离级别,则mysql会默认使用RR。

对隔离级别做了基本了解后,就针对工作中可能会用到的RR以及RC进行实际验证下,读未提交和可串行化本文就不继续谈了,我们还是以实战解决问题为主,不专做学术研究[去污粉]。

  1. RC(读已提交),验证方式为:首先打开会话1,设置此会话隔离级别为RC,并开始事务,查询sys_user表数据。打开另一个会话2,开启事务,对sys_user的部门数据进行修改,修改后先不提交.在会话1中再次查询sys_user表数据,具体操作如下图,这样就可以解决脏读问题了

接下来,在会话2中进行提交,操作,再回到会话1中查询sys_user表数据,发现虽然仍在一个事务中,两次一模一样的sql,事务内对数据也没修改,查询的结果数据却不一样,如下图。这就是不可重复读问题。

  1. RR(可重复读),验证方式为,先在会话1中设置查询级别为RR,开启事务后,查询sys_user表数据。在会二中开启事务,并对sys_user表的数据进行更新,更新后提交事务。此时查看数据库中sys_user的数据,发现库表数据已更新。最后在会话1中查询sys_user表数据,发现会话1中的数据并未修改,成功解决了可重复读的问题。如下图。

RR事务隔离级别还是比较特殊,有一些特殊的规则,这里列一下,别搞混了。首先RR事务级别是通过MVCC机制保证了数据的可重复度,内部是通过一个readview来实现历史版本的读取(具体下篇文章单独拉出来讲讲吧[吃瓜群众]比较复杂),因此RR隔离级别,select操作读取的历史版本,不过insert、update、delete是当前版本。

接下来是RR存在幻读情况验证。①先在会话1中设置查询级别为RR,开启事务后,查询sys_user表数据。②在会二中开启事务,并对sys_user表的数据进行插入,插入后提交事务。③在会话1中查询sys_user数据,发现会话2中的数据没有查询来。此处幻读看似解决。④在会话1对新增的数据执行update操作,⑤重新查询sys_user数据,发现新增了一条数据,幻读问题又来了[打脸],所以说RR没有办法彻底解决幻读问题。具体步骤如下图,方便直观感受[奸笑]

mysql的锁

mysql数据一致性,其实很多时候是靠锁来解决的,分为读锁和写锁,具体作用如下:

  • 读锁(共享锁、S):相当于在select 语句后面加上 lock in share mode,读锁为什么说是共享锁呢?因为加了读锁,是不影响其他事务读取此数据的,只是不允许其他事务修改
  • 写锁(排他锁,X):相当于在select 语句后面加for update,写锁是排他锁,其他事务的读取、和写入操作都要被阻塞,在mysql中,如果你在事务中写update、select、insert都会对数据加上写锁

关于事务的简单优化方案

了解完mysql事务后,那在实际业务中,就有一些要注意的事项了,我整理如下事项:

  1. 做好数据库连接池的配置,在并发条件下,如果多个事务被卡住,可能会导致数据库连接池被撑爆,从而导致系统异常
  2. 按需锁定数据,尤其是mysql有个间隙锁机制,如果一个表大量的数据区间被锁定,很可能会导致大量阻塞,最终应用内存溢出或者大量服务超时
  3. 严格避免死锁,死锁会导致资源一直不可用,最后导致排列的线程过多,内存占用越来越高
  4. 单个事务尽量小,不要一个事务内做过多操作,否则极其容易出现undolog过大、回滚耗时超长、连接池被撑爆等问题
  5. 部分数据一致性的操作可以在java解决,mysql的事务能避免还是避免下,毕竟数据库资源过于珍贵[狗头]
  6. 事务的超时时间一定要合理设置,不然有些事务等待过长,也是很容易导致内存溢出

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码