mysql事务和锁机制

mysql事务和锁机制

一、事务

1.事务的四大特性

​ 事务的四大特性是ACID,分别是原子性、一致性、隔离性和持久性。

  • 原子性:每一个事务都是最小的单位,一个事务中的操作要么完全成功,要么完全失败。
  • 一致性:事务中的操作要符合逻辑,在事务操作之后不能破坏数据库的完整。
  • 隔离性:事务之间是互不影响的、互不干扰的。
  • 持久性:当事务提交之后,就持久到磁盘中了,是永久性的。
2.事务并发的三大问题

2.1 脏读

​ 一个事务A读到了另外一个事务B修改但未提交的数据,导致事务A中两次读取的数据不一致,叫做脏读。
在这里插入图片描述

2.2 不可重复读

​ 在一个事务中,两次执行相同的查询操作却得到了不一样的结果,是由于读取到其他的事务更新/删除提交后的数据,这种叫做不可重复读。
在这里插入图片描述

2.3 幻读

​ 一个事务两次查询操作却得到了不同的结果,是由于读取到其他事务进行插入数据之后并提交后的数据,这种叫做幻读。
在这里插入图片描述

3.事务的四种隔离级别

​ 由于事务并发的一些问题,mysql使用隔离级别来解决这些问题。
在这里插入图片描述

3.1 读未提交

未提交读是最低的隔离事务级别,如果一个事务正在进行写操作,那么其实事务不能进行写操作,但允许其他事务读这行数据。

​ 一个事务会读到其他事务**未提交(commit)**的数据,这种隔离级别会产生脏读。

3.2 读已提交

​ 在”读已提交“的隔离级别中,如果是读操作,那么允许其他事务进行读写;如果是写操作,那么不允许任何事务进行访问该行数据。

解决了脏读的问题,但是并没有解决不可重复读的问题。

3.3 可重复读

​ 可重复读是InnoDB存储引擎的默认隔离级别,可重复读是指在一个事务中多次读取同一个数据,在这个事务还没有结束的时候,其他事务不能访问该数据(包括读写),这样就会保证事务在多次读取一个数据时的信息时一致,解决了脏读和不可重复读的问题。

​ 在InnoDB存储引擎中,使用Next-Key Lock锁的算法或者MVCC,避免的幻读的问题。

3.4 串行化

​ 串行化是事务的最高隔离级别,要求事务序列化执行,一个一个执行,不能并发执行,就不会出现脏读、不可重复读和幻读的问题,但是会导致效率太慢。

二、锁机制

1.行锁

1.1 共享锁(S锁)

定义

​ 又称读锁,顾名思义,共享锁就是多个事务对于一个同一个数据可以共享一把锁,都能访问的数据,但是只能读不能修改

加锁方式(SQL)

#加锁
select * from user where id = 1 lock in share mode
#释放锁
commit/rollback
1.2 排他锁(X锁)

定义

​ 又称为写锁,排他锁不能与其他锁共存,如一个事务获取了一行数据的排他锁,其他事务就不能再获取该行的锁(共享锁、排他锁),只有获取了排他锁的事务才能对该数据进行读取和修改

加锁方式(SQL)

#加锁的方式
#自动加锁,DML(增、删、改)语句会自动加上锁
delete/update/insert 默认加锁
#手动加锁
select * from user where id=1 for update;
2.表锁(意向锁)

​ 意向锁是数据库自己维护的,用户无法手动操作意向锁,可以理解意向锁是一个标志,并不是一个实质性的锁。

2.1 为什么需要意向锁?
  • 探路:InnoDB共享锁、排他锁是行锁,事务操作到行才发现被锁,非常耗费资源和浪费时间,因此表级的意向锁就很重要了。
  • 排他:在事务锁定某行前,先对表施加意向共享锁或意向排他锁,后来的事务就很方便知道自己是否可以施加某种锁了。
2.2 意向共享锁

​ 表示事务准备给一行数据加入共享锁,也就是说一个数据行加共享锁前必须先获得该表的IS锁。

2.3 意向排他锁

​ 表示事务准备给一行数据加入排他锁,也就是说一个数据刚要想加入一个排他锁前必须先获得该表的IX锁。

3.锁的原理

​ 加锁其实就是将锁加到了索引上。

4.InnoDB处理幻读

在这里插入图片描述

4.1 记录锁(Record)

​ 记录锁总是会锁住索引记录,如果InnoDB存储引擎表在简历的时候没有设置任何一个索引,那么这是InnoDB存储引擎会使用隐式的主键进行锁定。

  • 记录锁是锁住非主键索引,会在索引记录上加锁后,再去主键索引上加锁

  • 如果表中没有索引,那么会在隐藏的主键上加锁

  • 如果要锁的列没有索引,会进行全表加锁

    唯一性索引(主键/唯一)索引等值查询,精准匹配。

#会锁住id=4
select * from user where id=4 for update;
4.2 间隙锁(Gap)

​ 不是针对某一记录加锁,而是锁定一个范围,不会阻塞其他gap锁,但会阻塞插入间隙锁,这也是防止幻读的关键。
在这里插入图片描述

#所查询的记录刚好避开了4和7,避开了记录锁
select * from user where id>4 and id<7 for update

#会被锁住
select * from user where id=6 for update
4.3 临键锁(Next-key)

​ 临键锁就是记录锁+间隙锁,并且锁定记录本身,InnoDB的幻读就是由这个解决的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL事务锁机制数据库管理系统中重要的概念。事务是一组数据库操作(例如插入、更新、删除等)的执行单元,要么全部成功执行,要么全部回滚。锁机制用于管理并发访问数据库时的数据一致性和并发控制。 在MySQL中,事务由以下四个特性组成,通常简称为ACID: 1. 原子性(Atomicity):事务中的操作要么全部完成,要么全部回滚,不存在部分完成的情况。 2. 一致性(Consistency):事务开始和结束时,数据库的状态必须是一致的。即事务执行前后,数据库中的数据必须满足预定义的完整性约束。 3. 隔离性(Isolation):并发执行的事务之间相互隔离,一个事务的执行不应该受其他事务的影响。 4. 持久性(Durability):一旦事务提交,其结果应该永久保存在数据库中,即使发生系统故障也不会丢失。 MySQL中的锁机制用于控制对数据的并发访问。主要有两种类型的:共享(Shared Lock)和排他(Exclusive Lock)。共享允许多个事务同时读取同一数据,但不允许并发写操作。排他则只允许一个事务独占地进行读写操作。 MySQL提供了多种级别的,包括表级、行级和页面。表级是最粗粒度的,对整个表进行加;行级是最细粒度的,只对操作的行进行加;页面介于表级和行级之间,对一定范围的行进行加。 通过合理使用事务锁机制,可以确保数据库的数据一致性和并发控制,避免脏读、不可重复读和幻读等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值