美文网首页
mysql锁记录

mysql锁记录

作者: sizuoyi00 | 来源:发表于2022-04-19 00:20 被阅读0次

mysql锁

性能:乐观锁,悲观锁

操作类型:读锁,写锁,都属于悲观锁

操作粒度:行锁,表锁


乐观锁:一种思想,通过版本控制,字段控制
悲观锁:读锁,写锁

行锁:每次锁住一条数据;开销大,加锁慢;可能出现死锁;发生锁冲突概率低,并发高。
innoDB支持行锁,其是针对索引加的行级锁,没有索引会升级为表锁。demo参考:https://www.cnblogs.com/bestzhang/p/10278592.html
innodb会分析使用索引和全表扫描的开销,选择是否使用索引,也会导致即使我们认为使用索引对应行锁,但实际也是表锁。具体分析见上文trace工具

表锁:每次锁住整张表;开销小,加锁快;不会出现死锁;发生锁冲突概率高,并发低。
myisam支持表锁,每次查询会加读锁,增删改会加写锁。

读锁:读锁阻塞任意session的写,不阻塞任意session的读;其他session可以再加读锁,不可以加写锁。
select * from table where xxx lock in share mode;

写锁:写锁阻塞其他session的任意读写操作,不阻塞当前session的读写操作;其他session不可以加任意锁。
select * from table where xxx for update;

间隙锁(Gap Locks)(重点)
间隙锁是封锁索引记录中的间隔,或者第一条索引记录之前的范围,又或者最后一条索引记录之后的范围。

临键锁
是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。

1.唯一索引只有锁住多条记录或者一条不存在的记录的时候,才会产生间隙锁,指定给某条存在的记录加锁的时候,只会加记录锁,不会产生间隙锁;
2.普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;
3.间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,这是为了防止出现 幻读 现象;
4.事务级别是RC(读已提交)级别的话,间隙锁将会失效。
5.普通索引的间隙,优先以普通索引排序,然后再根据主键索引排序

意向锁
意向共享锁(IS)表示事务意图在表中的单个行上设置共享锁。
意向排他锁(IX)表明事务意图在表中的单个行上设置独占锁。

为什么需要意向锁
当事务A需要给表中表O某一行数据加行锁时,事务B想对表O加表锁;此时事务A与事务B是有冲突的,如果事务B要判断能够给表O加表锁,需要判断该表所有索引数据是否有加锁,全部没有此时才能加表锁,这样无疑是低效的;
意向锁:事务A——获得IX锁——对某行上X锁,事务B想对这个表上X锁,判断存在IX锁,事务B阻塞
IX,IS是表级锁

死锁
https://cloud.tencent.com/developer/article/1181187?from=15425
https://cloud.tencent.com/developer/article/1181180?from=15425
注意:innodb 日志中如果提示 lock mode S /lock mode X ,其实是gap锁,如果是行记录锁会提示but not gap


事务(隔离级别,传播行为,mvcc,事务失效)https://www.jianshu.com/p/9a0b6e07df61

ACID
原子性:所有操作要么全部执行,要么都不执行
一致性:事务开始与结束,数据要保证一致状态
隔离性:独立执行,也就是中间状态外部不可见
持久性:数据操作结果的永久性

脏读:session1修改了数据,session2读到了该数据,session1又回滚了,session2读的就是脏数据
不可重复读:session2使用固定条件查询,session1修改了数据并提交,session2用同样的条件查询发现数据不一致
幻读:session2使用固定条件查询,session1新增了数据并提交,session2用同样的条件查询发现数据不一致

读未提交(READ UNCOMMITTED):可以读到其他事物未提交的数据。
读已提交(READ COMMITTED):可以读到其他事物修改+新增并提交的数据,避免脏读,会出现不可重复度和幻读。
可重复读(Repeatable Read):可以读到其他事物新增并提交的数据,避免脏读与不可重复读,会出现幻读,但是mysql底层通过mvcc将幻读做了很大优化。
串行化(SERIALIZABLE):两个事物顺序执行,避免脏读,不可重复读和幻读。通过两阶段锁实现,获取到sql(行/表)资源时加锁,整个事物结束才会释放锁。具体加读锁还是写锁不确定,估计是根据sql来的。

mvcc并发版本控制
只在RC和RR起作用,因为RU获取最新数据,串行化加锁,与并发版本控制概念冲突
innodb在数据库每行数据后边默认添加三个字段
1.事务id(DB_TRX_ID):标识最后一次修改(insert/update)本行记录的事务id,操作一次+1,删除在innodb内部视为更新,该记录标识位标记为已删除
2.回滚指针(DB_ROLL_PTR):指向写入undolog的数据记录
3.主键id(DB_ROW_ID):没有主键会生成,有则不生成

快照读:普通的查,属于快照读,不加锁
当前读:特殊的查,如select ... lock in share mode,select ... for update,insert,update,delete),属于当前读,需要加锁

mvcc快照读原理以及RR与RC实现区别--查询原理
https://blog.csdn.net/SeekN/article/details/118552170
只有其他事物修改了数据才会生成事物id,普通查询会生成一致性视图read view,readview由未提交的事务id数组(最小的min_id)和已创建(未提交+提交)的最大事务id(最大的max_id)组成,查询时跟readview作对比得到快照结果。--readview:[100,200],300

如果是RR,当前事务会在第一次查询时候生成的readview作为快照结果也就是事物300,后续其他事务如事物100事物200有修改数据并提交,当前事务再次查询时会使用第一次查询的readview得到的快照结果,所以RR可以避免不可重复度(两次查询结果数据一致),并且可以避免部分幻读(普通查询使用快照读没问题,但是特殊查询/修改等操作会使用当前读)。

注意:上边说的第一次查询是以事务session为级别,只要有一条查询,无论查的是哪张表,readview就生成了。

如果是RC,当前事务在第一次查询时候生成的readview作为快照结果,后续其他事务有修改数据并提交,当前事务再次查询时重新计算最新的readview生成快照结果,也就是会产生不可重复读(两次查询结果数据不一致)

小结
RC:开启事务后,每次select都会重新创建ReadView
RR:开启事务后,每次select时,创建ReadView

mvcc增删改原理
修改:写锁锁定该行数据(最新版本,使用的是当前读获取数据),记录redolog,将当前的数据赋值到undo log,修改表中当前值行的值,修改事务编号,修改回滚指针指向undo log中修改前的行。
删除:删除可以认为是修改的特殊情况,也会将最新版本数据复制一份并修改回滚指针等,同时会在该条记录的头信息(record header)中的deleted_flag标志位改为true,表示该记录已经被删除。

redo/undo/binlog
重做日志redolog:事务开始就写入redolog,事务执行过程中,会直接写入,事务提交后,redolog就完成了使命释放掉。通过redolog保证事务的持久化。redolog是基于事务层面的;redolog是数据修改的物理记录。
回滚日志undolog:事务发生之前,当前数据的版本,可用于事务回滚,可用于mvcc快照读。事务提交后不会立即删除,有专门的线程会通过回滚指针等信息判断是否是老的undolog从而进行清理。
二进制日志binlog:用于主从同步,事务提交后将所有数据记录到binlog中,超过配置的天数后释放。binlog是基于数据库层面的;binlog可以认为是逻辑语句sql。

传播行为

解决@Transactional注解不回滚
是否为innodb引擎,异常类型是否支持,是否被catch住了
是否开启注解的解析,spring是否能扫描到对应的包
是不是public方法,是不是内部方法调用
解决内部方法调用:在当前处理service中注入本身service,自调用

相关文章

  • MySQL记录锁、间隙锁、临键锁(Next-Key Locks)

    MySQL记录锁、间隙锁、临键锁(Next-Key Locks)详解[https://www.jianshu.co...

  • mysql锁记录

    mysql锁 性能:乐观锁,悲观锁 操作类型:读锁,写锁,都属于悲观锁 操作粒度:行锁,表锁 乐观锁:一种思想,通...

  • MySql InnoDB 锁机制

    MySQL InnoDB支持三种行锁定方式: l 行锁(Record Lock):锁直接加在索引记录上面,锁住...

  • Mysql的锁

    MySql锁的分类 Mysql里的锁大致可以分为全局锁、表级锁和行锁三类。 全局锁 Mysql 增加全局锁的方法:...

  • mysql 排它锁之行锁、间隙锁、后码锁

    MySQL InnoDB支持三种行锁定 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。 ...

  • MySQL二进制日志

    MySQL-day10 MySQL存储引擎-锁 1)什么是“锁”? 2)“锁”的作用是什么? 3)MySQL中的锁...

  • MySQL 死锁 注意事项!

    mysql的锁分为三种(按照锁定的行数划分): 1.record lock:记录锁,也就是仅仅锁着单独的一行 2....

  • MySQL的锁机制

    mysql的锁机制 1、MySQL锁的基本介绍 MyISAM:MySQL的表级锁有两种模式:表共享读锁(Table...

  • MS汇总

    数据库相关[MS-关于锁(乐观锁,悲观锁,行锁、表锁,共享锁,排他锁)Mysql索引优化Mysql查询优化Mysq...

  • Innodb中的MVVC

    Mysql中有读锁和写锁,在没有引入MVVC之前,读锁是允许共享读,但是如果一行记录事先被上了写锁,那么就不允许其...

网友评论

      本文标题:mysql锁记录

      本文链接:https://www.haomeiwen.com/subject/zwgjertx.html