栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MySQL的事务与锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MySQL的事务与锁

目录

什么是事务

事务的特性

事务并发产生的问题

事务隔离级别

事务隔离级别的实现

MVCC

Read View(一致性视图)

锁(LBCC)

锁的算法


什么是事务

        事务就是一条sql语句或者多条sql语句所组成的逻辑执行单元,要么全部执行成功要么全部执行失败,目的是保证数据的一致性。

并不是所有的存储引擎都支持事务,InnoDB,NDB是支持事务的。

事务的特性

        在Mysql中事务的四大特性主要包含:原子性(Atomicity)、一致性(Consistency)、隔离性(lsolation)、持久性(Durability),简称为ACID。

原子性:指事务的原子性操作,即对数据的修改要么全部执行成功要么全部执行失败。是基于undo日志来实现的。一致性:指执行事务前后要状态要一致,可以理解成数据的一致性。隔离性:隔离性侧重指事务之间相互隔离,不受影响,这个与事务设置的隔离级别有密切的关系。持久性:指在一个事务提交后,这个事务的状态会被持久化到数据库中。是基于redo日志来实现的

原子性、隔离性、持久性都是为了保障一致性而存在的,一致性也是最终的目的。

事务并发产生的问题

脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。

不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外—个事务对数据进行了修改,这时候两次读取的数据是不一致的。(update/delete)

幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数据,这时候第一个事务就会丢失对新增数据的修改。(insert)

事务隔离级别

        在Mysql中事务的隔离级别分为四大等级,读未提交(READ UNCOMMITTED)、读提交 (READ COMMITTED)、可重复读 (REPEATABLE READ)、串行化 (SERIALIZABLE)。MySql默认的隔离级别是可重复读。

读未提交:可以读取另一个事务没有提交的数据。没有解决任何并发问题

读已提交:读取最新数据,可以读取另一个事务提交了的数据。解决了脏读问题。

可重复读:在同一个事务中多次读取同样的数据结果是一样的。解决了脏读和不可重复读,没有解决幻读。

串行化:最高的隔离级别,通过强制事务的串行执行。没有并发性可言,性能差。

InnoDB存储引擎在RR级别就解决了幻读问题。

事务隔离级别的实现

Read Uncommited :不加锁

Serializable:所有的select语句都会被隐式的转化为select ... in share mode,会和update.delete互斥。

RR 与 RC

RRRC
普通的select(快照读)MVCCMVCC

加锁的select和更新(当前读)

select ... in share mode

select ... for updateinsert
update

delete

Record Lock

Gap Lock
Next-key Lock

Record Lock

RC和RR的主要区别:

RR的间隙锁会导致锁定范围的扩大。条件列未使用到索引,RR锁表,RC锁行。RC的“半一致性”(semi-consistent)读可以增加update操作的并发性。

MVCC

多版本并发控制,也叫快照读,非阻塞读。 

lnnodb为每行记录都实现了三个隐藏字段

DB_ROW_ID  6字节:行标识DB_TRX_ID  6字节:插入或更新行的最后一个事务的事务ID,自动递增(创建版本号)DB_ROLL_PTR  7字节:回滚指针(删除版本号)

快照读效果:建立了一个快照,同一个事务无论查多少次都是相同的数据。
一个事务能看到的数据版本:

第一次查询之前已经提交的事务的修改本事务的修改

一个事务不能看见的数据版本:

在本事务第一次查询之后创建的事务(事务ID比我的事务ID大)活跃的(未提交的)事务的修改

MVCC基于Read View和undo log来实现

Read View(一致性视图)

RR的 Read View是事务第一次查询的时候建立的。

RC的 Read View是事务每次查询的时候建立的。

m_ids{}里是活跃的事务id,也就是还没提交的事务

min_trx_id是m_ids里子最小的事务id,也就是未提交事务的最小id,所以小于它的一定都提交了

max_trx_id是m_ids里子最大的事务id+1(代表即将分配的id),所以大于它的是生成ReadView之后才开启的事务,所以是读不到了。

creator_trx_id是生成ReadView事务的id,也就是当前事务的id.

 Read View判断规则

    从数据的最早版本开始判断(undo log)数据版本的trx_id = creator_trx_id,本事务修改,可以访问数据版本的trx_id <= min_trx_id(未提交事务的最小ID),说明这个版本在生成ReadView已经提交,可以访问数据版本的trx_id >= max_trx_id(下一个事务ID),这个版本是生成ReadView之后才开启的事务建立的,不能访问数据版本的trx_id在min_trx_id和max_trx_id之间,看看是否在m_ids中。如果在,不可见。如果不在,可见。如果当前版本不可见,就找undo log链中的下一个版本。

锁(LBCC)

锁的本质是什么:锁的本质是锁索引,如果非索引的字段加锁会导致锁表。

锁的粒度

MyISAM和InnoDB分别支持什么粒度的锁?

InnoDB支持行锁和表锁,而MyISAM只支持表锁。

表锁与行锁的区别:

锁定粒度∶ 表锁 > 行锁加锁效率:表锁 > 行锁冲突概率:表锁 > 行锁并发性能:表锁 < 行锁

InnoDB锁类型

共享锁(行锁):Shared Locks排它锁(行锁):Exclusive Locks意向共享锁(表锁):Intention Shared Locks意向排它锁(表锁):Intention Exclusive Locks

.共享锁

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

加锁释锁方式:

select * from student where id=1 LOCK IN SHARE MODE;

锁会在事务提交或者回滚时释放,或者当连接断开也会释放锁。

拿不到锁的事务会等待,默认等待50s

排他锁

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

加锁释锁方式:

自动: delete / update / insert 默认加上X锁;
手动: select* from student where id=1 FOR UPDATe;

意向锁

意向锁是由数据引擎自己维护的,用户无法手动操作意向锁。

在我们加行锁的时候,存储引擎会帮们加上表锁。(这大大提高了加表锁的效率)

意向共享锁(Intention shared Lock,简称IS锁)表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁。

意向排他锁(Intention Exclusive Lock,简称IX锁)表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

死锁的避免

顺序访问数据排序申请足够级别的锁避免没有where条件的操作大事务分解成小事务使用等值查询而不是范围查询

锁的算法

记录锁(Record):在指定的一行数据加记录锁

间隙锁(Gap):在范围加锁时,范围内没有数据,会给这个间隙加间隙锁。间隙锁的最大作用就是阻塞插入,可以解决幻读问题。

临建锁(Next-key):记录锁+间隙锁。范围加锁时,范围内有数据,会加临建锁,

记录锁

 间隙锁

 临建锁

select * from t2 where id>1 and id <7 for update;

锁住的范围是(1, 7]

select * from t2 where id>1 and id <=7 for update;

锁住的范围是(1, 10]

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778431.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号