mysql之事务和锁机制(代码片段)

一只咸鱼。。 一只咸鱼。。     2023-04-08     680

关键词:

文章目录


提示:以下是本篇文章正文内容,MySQL 系列学习将会持续更新

一、事务

  • 在数据库里面,我们希望有些操作能够以原子的方式进行,要么都能执行成功,要么就都不执行,也就是只能是一个整体的被执行,这样的一组具有原子性的操作我们就称之为事务
  • 我们的 MySQL 支持 9 种数据库引擎,但只有默认的 Innodb 引擎支持事务功能。

1.1 事务特征

  • 原子性 (atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
  • 一致性 (consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
  • 隔离性 (isolation):当多个事务对同一资源同时操作时,一个事务的执行不能被其他事务干扰。这里的同时只是宏观上的表现,实际上也就是微观上同一时刻只有一个事务在执行,而其它事务是在等待中。
  • 持久性 (durability):指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,即便系统故障也不会丢失。

1.2 隔离级别

更追求隔离性(数据更正确)-------------------------------------------------------------------------------------------------------------->更追求并发性(性能更高)
(可串行性)
serializable
(快照读)
snapshot_read
(可重复读)
repeatable_read
(读已提交)
read_committed
(读未提交)
read_uncommitted

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。



不是标准中存在的隔离级别,目前来说,没有副作用。
MySQL中的可重复读就是实际上的快照读。因为MVCC机制解决了幻读


这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。这会导致幻读当用户修改某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有一条未修改的数据“幻影”只能读取其它事务已经提交的内容,存在不可重复读问题:一个事务多次读取同一数据可能会得到多个不同的结果



能够读取到其它事务中未提交的内容,存在脏读问题。读取未提交的数据,也被称之为脏读




我们可以修改隔离级别:

set session transaction isolation level read uncommitted;

回到目录…

1.3 开启事务

①SQL开启事务

-- 开启事务
start transaction; / begin;
SQL1;
SQL2;
rollback; -- 主动回滚

-- 开启事务
start transaction; / begin;
SQL1;
SQL2;
SQL3;
commit; -- 提交事务,失败也会回滚

②JDBC使用事务

// 要使用事务,在同一个事务中,操作 sql1 和 sql2,意味着必须在一条 Connection 完成
try (Connection c = DBUtil.connection()) 
    // connection 中有一个自动提交(autocommit)的属性,默认情况下是 true(开启)
    // 开启状态下,意味着,每一条 sql 都会被独立的视为一个事务
    // 我们要让 sql1 和 sql2 看作整体,只需要关闭 connection 的自动提交
    c.setAutoCommit(false);
    // 此时就可以手动的控制事务的结束位置,并且需要手动提交

    try (PreparedStatement ps = c.prepareStatement(sql1)) 
        ps.executeUpdate();
    

    try (PreparedStatement ps = c.prepareStatement(sql2)) 
        ps.executeUpdate();
    

    // 由于我们关闭了自动提交了,所以,所有的修改还没有真正地落盘
    c.commit();     // 只有加上这句话,才表示事务被提交了(数据真正落盘了)

回到目录…

二、锁机制

我们知道在可重复读的级别下,MySQL 在一定程度上解决了幻读问题:

  • 在快照读(不加锁)读情况下,mysql 通过 MVCC (多版本并发控制) 来避免幻读。
  • 在当前读(加锁)读情况下,mysql 通过 next-key 来避免幻读。

2.1 读锁、写锁

从对数据的操作类型上来说,锁分为读锁和写锁:

  • 读锁:也叫共享锁,当一个事务添加了读锁后,其他的事务也可以添加读锁或是读取数据,但是不能进行写操作,只能等到所有的读锁全部释放。
  • 写锁:也叫排他锁,当一个事务添加了写锁后,其他事务不能读不能写也不能添加任何锁,只能等待当前事务释放锁。

2.2 全局锁、表锁、行锁

从锁的作用范围上划分,分为全局锁、表锁和行锁:

全局锁:锁作用于全局,整个数据库的所有操作全部受到锁限制。

flush tables with read lock;

表锁:锁作用于整个表,所有对表的操作都会收到锁限制。

lock table 表名称 read; -- 读锁
lock table 表名称 write; -- 写锁

-- 除了手动释放锁之外,当我们的会话结束后,锁也会被自动释放。
unlock tables;

行锁:锁作用于表中的某一行,只会通过锁限制对某一行的操作(仅InnoDB支持)

-- 添加读锁(共享锁)
select * from 表名 where ... lock in share mode;
-- 添加写锁(排他锁)
select * from 表名 where ... for update;

回到目录…

2.3 记录锁、间隙锁、临键锁

我们知道 InnoDB 支持使用行锁,但是行锁比较复杂,它可以继续分为多个类型,详细可查看文章:MySQL的锁机制 - 记录锁、间隙锁、临键锁

记录锁(Record Locks): 仅仅锁住索引记录的一行,在单条索引记录上加锁。Record lock 锁住的永远是索引,而非记录本身。所以说当一条 sql 没有走任何索引时,那么将会在每一条聚合索引后面加写锁,这个类似于表锁,但原理上和表锁应该是完全不同的。

  • id 列必须为唯一索引列或主键列,否则加的锁就会变成临键锁。
  • 同时,查询语句必须为精准匹配(=),不能为 >、<、like等,否则也会退化成临键锁。

间隙锁(Gap Locks): 仅仅锁住一个索引区间(开区间)。在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。比如在 1、2 中,间隙锁的可能值有 (-∞, 1),(1, 2),(2, +∞),间隙锁可用于防止幻读,保证索引间的不会被插入数据。

  • 对于主键索引:精准查询存在列,只会产生记录锁;精准查询不存在列,会产生记录锁和间隙锁;范围查询会产生间隙锁。
  • 对于普通索引:不管是何种查询,只要加锁,都会产生间隙锁。

临键锁(Next-Key Locks): Record lock + Gap lock左开右闭区间。默认情况下,InnoDB 正是使用 Next-key Locks 来锁定记录(如select … for update)。

它还会根据场景进行灵活变换:

场景转换
使用唯一索引进行精确匹配,但表中不存在记录自动转换为 Gap Locks
使用唯一索引进行精确匹配,且表中存在记录自动转换为 Record Locks
使用非唯一索引进行精确匹配不转换
使用唯一索引进行范围匹配不转换,但是只锁上界,不锁下界

回到目录…


总结:
提示:这里对文章进行总结:
本文是MySQL的学习,先学习了事务的四大特征、隔离级别,如何开启事务。又学习了锁机制,认识了读写锁、行表锁、记录锁等。之后的学习内容将持续更新!!!

工作四年都没搞定的mysql事务和锁机制,这篇一次讲清!(代码片段)

前言众所周知,事务和锁是mysql中非常重要功能,同时也是面试的重点和难点。本文会详细介绍事务和锁的相关概念及其实现原理,相信大家看完之后,一定会对事务和锁有更加深入的理解。什么是事务在维基百... 查看详情

redis6事务和锁机制(代码片段)

目录事务基本操作错误机制悲观锁乐观锁Redis事务三特性秒杀案例超卖问题连接超时问题库存遗留问题事务        Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中ÿ... 查看详情

redis6事务和锁机制(代码片段)

目录事务基本操作错误机制悲观锁乐观锁Redis事务三特性秒杀案例超卖问题连接超时问题库存遗留问题事务        Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中ÿ... 查看详情

mysql事务和锁(代码片段)

1.事务2.锁  1.事务什么是事务?事务是指一组业务操作,要么全部成功,要么全部失败。比如银行转账业务,步骤一:从A账户减少300元;步骤二:向B账户增加300元。为了确保总的金额不变,就要维持数据的一致性,那么... 查看详情

深入了解mysql的隔离级别和锁机制

简述:我们的MySQL一般会并发的执行多个事务,多个事务可能会并发的对同一条或者同一批数据进行crud操作;可能就会导致我们平常所说的脏读、不可重复读、幻读这些问题.这些问题的本质都是MySQL多事务并发问题,为了解决多事务... 查看详情

mysql事务和锁(代码片段)

一,锁锁是并发控制中最核心的概念之一,在MySQL中的锁分两大类,一种是读锁,一种是写锁,读锁也可以称为共享锁(sharedlock),写锁也通常称为排它锁(exclusivelock)。  这里先不讨论锁的具体实现,描述一下锁的概念:... 查看详情

高频|mysql事务隔离级别和锁的机制可以这么答

...例分析案例解答死锁产生的四个必要条件:案例背景MySQL的事务隔离级别(IsolationLevel),是指:当多个线程操作数据库时,数据库要负责隔离操作,来保证各个线程在获取数据时的准确性。它分为四个不同... 查看详情

mysql并发问题(代码片段)

SERIALIZABLE解决上面说的所有事务并发问题,但事务是串行执行的。INFORMATION_SCHEMA中与事务和锁相关的表INFORMATION_SCHEMA中与事务和锁相关的表有如下几个:INFORMATION_SCHEMA.INNODB_TRXINFORMATION_SCHEMA.INNODB_LOCKSINFORMATION_SCHEMA.INNODB_L 查看详情

事务和锁机制是啥关系?开启事务就自动加锁了吗?菜鸟,谢谢了。

1、事务与锁是不同的。事务具有ACID(原子性、一致性、隔离性和持久性),锁是用于解决隔离性的一种机制。2、事务的隔离级别通过锁的机制来实现。另外锁有不同的粒度,同时事务也是有不同的隔离级别的。3、开启事务就... 查看详情

orm中的事务和锁(代码片段)

锁models.Book.objects.select_for_update().filter(id=1)事务?全局开启事务#当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求正确处理并正确返回了结果,Django就会提交该事务。否则,Django会回滚该事务。DATABASES='default&#... 查看详情

深入剖析mysql事务和spring事务(代码片段)

本文分享一些关于Mysql如何解决多事务并发的问题和Spring源码是怎么控制事务以及一些事务失效的场景。分享内容Mysql事务隔离机制锁机制MVCC多版本并发控制隔离机制Spring事务应用和源码分析事务失效问题一、Mysql事务数据库的... 查看详情

mysql基础篇(06):事务管理,锁机制案例详解(代码片段)

...的模块,贯彻MySQL的几大核心难点模块:索引,锁机制,事务。这里是基于MySQL5.6演示的几种典型场景,对面MySQL这几块问题时,有分析流程和思路是比较关键的。在MySQL中常见这些锁概念:共享读锁、排它写锁;表锁、行锁、间隙... 查看详情

mysql中的事务控制机制(代码片段)

事务控制是MySQL的重要特性之一。在MySQL中,InnoDB和NDBCluster是常见的事务型存储引擎。1.自动提交默认情况下,MySQL是自动提交(autocommit)的。也就意味着:如果不是显式地开始一个事务,每个查询都会被... 查看详情

rabbitmq:消息确认机制之事务机制(代码片段)

...se,false,false,null);//创建一个消息stringmsg="helloworld";try//开启事务机制//事务机制性能不好,不建议使用.因为需要和服务器发生额外的通信,降低了RabbitMQ的吞吐量channel.TxSelect();//发送消息channel.BasicPublish("",QueueName,null,Encoding.Default.GetByt... 查看详情

mq确认机制之事务机制----confirm串行(代码片段)

一:介绍1.说明原理  A:生产者将信道设置成confirm模式,一旦信道进到confirm模式,所有该信道上发布的消息都会被指派一个唯一的ID(从1开始)。  一旦消息被投递到所有匹配的队列后,broker就会发送一个确认给生产者,并... 查看详情

mysql中的锁机制(代码片段)

...是为了解决问题而生的,锁被用来实现隔离性,保证并发事务的正确性。两段锁&一次封锁两段锁数据库遵循的是两段锁协议,将事务分成两个阶段,加锁阶段和解锁阶段(所以叫两段锁)加锁阶段:在加锁阶段只能进行加锁... 查看详情

mysql原理篇之事务--08(代码片段)

Mysql原理篇之事务--08引言ACID事务的状态事务的语法支持事务的存储引擎自动提交隐式提交保存点小结引言上一篇文章。本文为事务原理篇,如果对事务基础概念还有不清楚的,建议看一下事务基础篇,假设我们有如下两条... 查看详情

一文详解-mysql事务和锁

...的更新从一个一致性状态变为另外一个一致性状态,使用事务处理是非常必要的,事务具有以下四个特性:MySQL提供了多种事务型存储引擎,如InnoDB和BDB等,而MyISAM不支持事务。为了支持事务,InnoDB存储引擎引入了与事务处理相... 查看详情