首页 > 数据库 >MySQL_事务

MySQL_事务

时间:2023-11-26 10:34:44浏览次数:36  
标签:事务 记录 Read trx MySQL id View

事务的特性

ACID

  1. A原子性:一个事务中的所有操作,要么全部完成,要么全部不完成。undo log保证
  2. C一致性:事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。原子性、隔离性、持久性保证
  3. I隔离性:多个并发事务交叉执行,使用相同的数据时,互不干扰,每个事务都有一个完整的数据空间。MVCC或锁机制保证
  4. D持久性:事务处理结束后,对数据的修改是永久的,即便系统故障也不会丢失。redo log保证

并行事务会引发什么问题

  1. 脏读:一个事务读到了,另一个未提交事务修改过的数据
  2. 不可重复读:一个事务内多次读取同一个数据,前后两次读到的数据不一样
  3. 幻读:一个事务内多次查询某个符合查询条件的记录数量,前后两次查询到的记录数量不一致

事务的隔离级别有哪些

  1. 未提交读:
  2. 已提交读:MyISAM默认的隔离级别。彻底解决脏读
  3. 可重复读:InnoDB默认的隔离级别。彻底解决脏读、不可重复读(部分解决幻读)
  4. 串行化:彻底解决脏读、不可重复读、幻读

事务的隔离级别是如何实现的

  1. 未提交读:直接读取最新的数据。
  2. 串行化:加读写锁。
  3. 已提交读和可重复读:通过Read View来实现的。创建的时机不同。(已提交读:每个语句执行之前。可重复读:启动事务时。

可重复读如何部分解决幻读

  1. 针对快照读SELECT:通过MVCC,事务执行过程中看到的数据,和事务启动时看到的数据时一致的。
  2. 针对当前读SELECT...FOR UPDATE:通过next-key lock(记录锁+间隙锁)阻塞其他事务的插入操作。

执行了“开始事务”就一定启动了事务吗?

不一定

  1. start/begin transaction 命令。之后执行第一条SELECE语句,才是事务真正启动的时机。
  2. start transaction with consistent snapshot命令。马上开启事务。

Read View 在MVCC里怎么工作?

Read View里的4个字段

creator_trx_id:创建该Read View的事务的id
m_ids:创建Read View时,当前数据库中活跃事务(启动了但还没提交的事务)的事务id列表。
min_trx_id:m_ids的最小值。
max_trx_id:全局事务中最大的事务id值+1。

聚簇索引记录中的两个隐藏列

trx_id:事务id。
roll_pointer:指向undo log中的旧版本记录。

trx_id与记录对事务可见性的关系

创建Read View后,trx_id的分类:
已提交事务min_trx_id已启动但未提交的事务(m_ids) max_trx_id还没有开始的事务

  1. trx_id小于min_trx_id,该版本的记录对当前事务可见。
  2. trx_id大于max_trx_id,不可见。
  3. trx_id在之间,在m_ids列表中,不可见。
  4. trx_id在之间,不在m_ids列表中,可见。
  5. trx_id和creator_trx_id相等,可见。
什么是MVCC?

通过版本链事务的Read View里的字段记录中的两个隐藏列的对比)来控制并发事务访问同一个记录时的行为。

可重复读是如何工作的

启动事务时生成一个Read View,整个事务期间都在用这个Read View。
读记录时判断trx_id,如果小于min_trx_id,或不在m_ids中,说明在生成Read View就已经提交修改了,可以读。否则,顺着roll_pointer在undo log中找,直到找到符合条件的trx_id。

已提交读是如何工作的

每次读取数据时,都会生成一个新的Read View。

MySQL可重复读隔离级别,完全解决幻读了吗

没有
幻读的2个例子:

  1. 对于快照读:事务A更新了一条事务B插入的记录x,那么事务A前后两次查询的记录条目就不一样了,就发生了幻读。(记录x的trx_id变成了事务A,对事务A就可见了)
  2. 对于当前读:先快照读,其他事务插入了一条记录,再当前读,前后两次查询的记录条目不一样,就发生了幻读。(锁加晚了)

如何避免:
在开启事务后,立马执行SELECT...FOR UPDATE,对记录加锁,避免其他事务插入数据。

标签:事务,记录,Read,trx,MySQL,id,View
From: https://www.cnblogs.com/espgod/p/17855698.html

相关文章

  • Windows环境下修改my.ini导致MySQL启动失败
    问题:修改my.ini导致MySQL启动失败在Windows环境中,使用默认编辑器编辑my.ini配置文件可能导致MySQL启动失败,是因为默认编辑器使用的是UTF-8编码。解决方法:更改编码为ANSI使用文本编辑器打开my.ini,选择“另存为”并将编码更改为ANSI。重新启动MySQL服务,确保配置文件与MySQL默认......
  • mysql多个字段最大最小值
    转自:https://www.jb51.net/article/263686.htm1、语法最大值:GREATEST(expr_1,expr_2,...expr_n)最小值:LEAST(expr_1,expr_2,...expr_n)2、说明GREATEST(expr_1,expr_2,...expr_n)函数从表达式(列、常量、计算值)expr_1,expr_2,...expr_n等中找出最大的数返回......
  • 关于点赞业务对MySQL和Redis和MongoDB的思考
    点赞​ 在我个人理解中,点赞业务比较频繁,很多人业务可能都会有这个,比如:博客,视频,文章,动态,评论等,但是不应该是核心业务,不应该大量地请求MySQL数据库,给数据库造成大量的资源消耗,MySQL的数据库是非常宝贵的.以某音为例,当我去搜索的时候,全抖音比较高的点赞数目应该是在1......
  • 在 Go-Kratos 框架中优雅的使用 GORM 完成事务
    准备工作创建新项目kratosnewhelloworldcdhelloworld#拉取项目依赖gomoddownload#项目中的config等请自行修改 添加事务如果您还不了解Kratos、mysql事务和GORM的话请先了解一下。data层承载事务是否比较合适?其实最简单也最直接的方法就是在da......
  • mysql定时备份
    mysql定时备份概述:​1、一般来说,生产服务器每天都需要定期进行数据备份、异地备份,这样确保意外情况(数据意外删除、硬件故障、火灾等等)下避免数据大批量丢失,能快速恢复数据,把意外带来的影响降到到最小。数据库数据备份尤为重要,而我们不会人工手动去备份,这样会很麻烦,我们都是通过......
  • ubuntu下mysql57重置密码
    重置密码:重置MySQLroot用户的密码。在安全模式下启动MySQL(root下),然后更改密码。sudoservicemysqlstopsudomysqld_safe--skip-grant-tables&mysql-uroot在MySQL中执行以下SQL语句:USEmysql;UPDATEuserSETauthentication_string=PASSWORD('your_new_pa......
  • windows中MySQL忘记密码
    前言:  一直都是连接公司项目数据库,许久未连接本地的数据库,密码忘记了 步骤:进入本机安装mysql的bin目录下暂停mysql服务 netstopmysql设置跳过密码授权登录 mysqld--console--skip-grant-tables--shared-memory 新开命令行窗口,输入mysql-uroot无密码登录修......
  • MySQL5.7允许远程root访问
    MySQL5.7允许远程root访问登录你的服务器MySQLmysql-uroot-pMySQLroot密码GRANTALLPRIVILEGESON*.*TO'root'@'%'IDENTIFIEDBY'你的root密码'WITHGRANTOPTION;......
  • [Mysql] 网站查询数据不是最新的数据
    一、发现问题近期部署一个内部服务站点,提供一个web界面供查询和展示分析后的数据报表,启动时一段时间内数据查询获取的都是最新值,等待几个小时后,网页查询出来的结果不是最新值,但是数据库中是存在更新的数据记录,不知何故?二、排查过程在MySQL中事务的隔离级别有4种类型:读未提交(READUN......
  • MySQL 从库变主库
    从库变主库一.在从库主机上:1.确认同步完成showslavestatus\G2.停止从库stopslave;#清空从库relaylog日志resetslave;#清除slave信息resetslaveall;查看是否清除showslavestatus\G3.清除binlogresetmaster;4从变主后,配置文件开启binlogid号别错了5.从库要重......