mysql事务与锁

事务acid原则

  1. 原子性
  2. 隔离性
  3. 一致性
  4. 持久性

事务的概念

把需要保证原子性、隔离性、一致性和持久性的一个或者多个数据库操作称为事务。

事务的使用

语法

begin;//开启一个事务
some sql;//需要执行的语句
savepoint bussiness1;//事务保存点
some sql;
roll back to bussiness1;//回滚
commit;//提交事务
rollback;//如果需要手动回滚的话在提交之前删除这句

事务的自动提交

通常情况下mysql默认自动提交事务。既每一个语句都都会直接提交事务,可以通过set autocommit=off来实现手动提交。

隐式提交

在一些操作下,哪怕在事务中也可能会自动把事务进行提交。

  1. 定义或者修改数据库对象的数据定义语言,指对数据库、表、视图、存储过程等进行修改。
  2. 隐式使用或者修改mysql数据库中的表:当我们使用ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、SET PASSWORD等语句时也会隐式的提交前边语句所属于的事务。
  3. 事务控制或关于锁定的语句:前一个事务尚未完成又开启事务时上一个会自动提交。使用lock tables、unlock tables等关于锁定的语句也会隐式提交之前的事务。
  4. 加载数据的语句:如果使用load data语句从文件中批量往数据库中插入数据时,也会隐式提交前边语句所属的事务。
  5. 其他: analyze table(统计表数据)、cache index()、check table、flush、load index into cache、optimize table、repair table。

事务的隔离级别

set session transaction isolation level [level];

level类型:

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
不可重复读、提交读(read-committed)
可重复读(repeatable read)
串行化(serializable)

翻了一通网上的文章和培训视频对脏幻不可重复读的理解就NM离谱……

去查了一下高性能mysql这本书。

脏读:

定义:事务中的修改,即使没有提交,对其他事务也是可见的。

实例:事务A查询记录1,事务B更新记录1(尚未commit),事务A再次查询记录1,得到事务B更新结果。

在rc级别上已经可以克服脏读的问题。

不可重复读:

定义:一个事务开始时,只能看见已经提交的事务所做的修改。

实例:事务A查询记录1,事务B更新记录1(commit),事务A再次查询记录1,得到事务B更新结果。

幻读:

定义:指的是当某个事务A在读取某个范围的记录时,另一个事务B又插入了一条,A再次查询时会得到查询出这条记录。

幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。

MVCC

innoDB存储引擎记录数据的行有三个隐藏列:

  1. row_id 行id 唯一标识记录(非必须)
  2. transaction_id 事务id (必须)
  3. roll_pointer 回滚指针(必须)

ReadView

select 时生成

对于RU级别的事务,直接读取最新记录的版本,对于使用Serializable级别的,使用加锁方式访问,使RC和RR级别的事务则需要使用版本链,核心:判断版本链中的哪个版本是当前事务可见的。

ReadView包含四个比较重要的内容:

  1. m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
  2. min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
  3. max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值。
  4. creator_trx_id:表示生成该ReadView的事务的事务id

在有了这个readview之后,需要按照下边步骤判断记录是否可见:

  1. trx_id与creator_trx_id相同,可见。
  2. 被访问版本的trx_id<min_trx_id,表明生成该版本的事务在当前事务生成readview前已经提交,所以该版本可以被访问。
  3. 如果trx_id>max_trx_id,表明该版本的事务在当前事务生成readview后才开启,不可以被当前事务访问
  4. 如果trx_id在min和max之间,需要判断一下trx_id属性值是不是在m_ids的列表中,如果在,说明生成该版本时,这个事务还是活跃的。该版本不可被访问;如果不在,则代表生成该版本时事务已经被提交,该版本可以被访问。

rc实现方式

每次读取数据前都生成一个readview。

rr实现方式

在第一次读取数据时生成一个readview

实例:

在RC级别下 原先数据为1

有两个事务A,B,时间线如下

B将数据更新,B此时可以读到2

此时A应该读更新前还是更新后的数据?

假设A的事务ID是100,B的是200

如果

min_trx_id=99,

max_trx_id=200;

m_ids=[99,100,200]

此时此时A事务符合规则4,读到的数据应该为1

关于锁

锁的分类

  1. 读锁:共享锁、shared Locks、S锁
  2. 写锁:排他锁、Exclusive Locks、X锁
X锁 S锁
X锁 冲突 冲突
S锁 冲突 不冲突

读操作

对于普通的select语句InnoDB不会加任何锁。

select …… lock in share mode

将查找到的数据加上一个S锁,其他事务能读,但是不能写。

读出数据后:其他事务不能修改,但自己也不一定能修改,因为有可能有别的事务也可以使用select lock in share mode继续加读锁。

select …… for update

加上一个X锁。

写操作

  1. delete:先加X锁,再执行删除。
  2. insert:插入一条记录时,会先加隐式锁来保护这条新加入的数据在本事务提交之前不被别的事务访问到。

    todo:隐式锁实现是啥呢……

  3. update
    1. 如果被更新的列修改前后没有导致存储空间变化,加X锁,修改记录。
    2. 如果被更新的列修改前后导致存储空间的变化,加X锁,删除,insert。

行锁与表锁

行锁

  1. LOCK_REC_NOT_GAP:单个行记录
  2. LOCK_GAP:间隙锁,锁定一个范围,但不包括记录本身。
  3. LOCK_ORDINARY:锁定一个范围以及记录本身。

原文地址:https://www.cnblogs.com/callmechen1997/p/11567367.html

时间: 2024-10-10 08:26:03

mysql事务与锁的相关文章

mysql事务和锁InnoDB(转)

背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因. 注:MySQL是一个支持插件式存储引擎的数据库系统.本文下面的所有介绍

mysql事务和锁InnoDB

背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因. 注:MySQL是一个支持插件式存储引擎的数据库系统.本文下面的所有介绍

Mysql 事务与锁机制

一. 事务四要素 数据库事务正确执行的四个基本要素包括原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability),简称ACID.目前要实现ACID主要有两种方式:一种是Write ahead logging,也就是日志式的方式(现代数据库均基于这种方式):另一种是Shadow paging. 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)

MySQL事务和锁 (四)

一 .事务 1.1 事务的概念 mysql把多条写操作视为一个整体去执行,要么全部成功,要么全部失败,我们把mysql的这种处理叫做事务.(“多条”很好理解就是至少两条sql语句,“写操作”就是指对msyql内容修改的操作(insert.update.delete)). 1.2事务的特性 原子性: 确保工作单元内的所有操作都成功完成,否则事务将被中止在故障点,和以前的操作将回滚到以前的状态. 一致性: 确保数据库正确地改变状态后,成功提交的事务. 隔离性: 使事务操作彼此独立的和透明的. 持久性

mysql事务和锁

尝试进行归纳总结事务和锁的一些思考. 数据库是什么? 保存数据的地方. 为什么保存数据要用数据库呢? 我直接把数据放文件里, 不也一样吗? 比如我自己序列化json文件保存成txt文件成不? 也行, 但是就不方便检索, 之类的. 数据库就方便检索了呀, 数据库相比文件系统有4个特点: A - 原子性 C - 一致性 I - 隔离性 D - 持久性 这里只说锁, 锁是用来保证隔离性的. 隔离性是啥? 比如, 我现在自己实现了一个不怎么完善的数据库, 只是按SQL标准实现了增删改查等命令, 但是操作

关于mysql事务行锁for update实现写锁的功能

 例子1: 在电子商务里,经常会出现库存数量少,购买的人又特别多,大并发情况下如何确保商品数量不会被多次购买. 其实很简单,利用事务+for update就可以解决. (for update仅仅适用于InnoDB) 我们都知道for update实际上是共享锁,是可以被读取的.但是如何在执行时,不被读取呢. 简单来说:假设现在库存为1,现在有A和B同时购买 先开启一个事务 begin; select stock from good where id=1 for update;//查询good表某

MySQL事务、锁

事务描述: 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务.事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行.事务它还可以用来管理DDL.DML.DCL操作,比如 insert,update,delete 语句.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性): 构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行 Consistency(稳定性.一致性):      数据库在事务执

[数据库事务与锁]详解六: MySQL中的共享锁与排他锁

注明: 本文转载自http://www.hollischuang.com/archives/923 在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大大减少数据库操作的冲突.行级锁分为共享锁和排他锁两种,本文将详细介绍共享锁及排他锁的概念.使用方式及注意事项等. 共享锁(Share Lock) 共享锁又称读锁,是读取操作创建的锁.其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁. 如果事务T对数

[数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁

注明: 本文转载自http://www.hollischuang.com/archives/914 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在数据库的锁机制中介绍过,在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM引擎)和页级锁(BDB引擎 ). 行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁.行级锁能大大减少数据库操作的冲突.其加锁粒度最小,但加锁的