mysql怎么用锁 mysql怎么锁住数据( 二 )


如果想锁住多份数据该怎么实现?比如说,某个库存操作,既要修改物理库存,又要修改虚拟库存,想锁住物理库存的同时 , 又锁住虚拟库存 。其实也不是很难,参考lock方法,写一个multiLock方法 , 提供多个transactionId的入参 , for循环处理就可以了 。这个后续有时间再补上 。
MySQL的锁分类以及使用场景InnoDB默认是行级别的锁mysql怎么用锁 , 当有明确指定的主键时候mysql怎么用锁,是行级锁 。否则是表级别 。
例子: 假设表foods ,存在有id跟name、status三个字段,id是主键,status有索引 。
例1: (明确指定主键,并且有此记录,行级锁)
例2: (明确指定主键/索引,若查无此记录 , 无锁)
例3: (无主键/索引 , 表级锁)
例4: (主键/索引不明确,表级锁)
for update的注意点
for update的疑问点
MySQL锁表和解锁操作1、确定mysql有锁表的情况则使用以下命令查看锁表进程
2、杀掉查询结果中已经锁表的trx_mysql_thread_id
扩展:
1、查看锁的事务
2、查看等待锁的事务
3、查询是否锁表:
4、查询进程
mysql 的锁以及间隙锁mysql 为并发事务同时对一条记录进行读写时mysql怎么用锁,提出了两种解决方案:
1)使用 mvcc mysql怎么用锁的方法,实现多事务的并发读写,但是这种读只是“快照读”,一般读的是历史版本数据,还有一种是“当前读”,一般加锁实现“当前读”,或者 insert、update、delete 也是当前读 。
2)使用加锁的方法,锁分为共享锁(读锁) , 排他锁(写锁)
快照读:就是select
当前读:特殊的读操作,插入/更新/删除操作,属于当前读 , 处理的都是当前的数据,需要加锁 。
mysql 在 RR 级别怎么处理幻读的呢?一般来说,RR 级别通过 mvcc 机制,保证读到低于后面事务的数据 。但是 select for update 不会触发 mvcc,它是当前读 。如果后面事务插入数据并提交,那么在 RR 级别就会读到插入的数据 。所以 , mysql 使用 行锁 + gap 锁(简称 next-key 锁)来防止当前读的时候插入 。
Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作 , 以此防止幻读的发生 。
Innodb自动使用间隙锁的条件:
详解MySQL(InnoDB)如何处理死锁 锁是需要事务结束后才释放的 。
一个是 MVCC,一个是两阶段锁协议 。
为什么要并发控制呢?是因为多个用户同时操作 MySQL 的时候,为了提高并发性能并且要求如同多个用户的请求过来之后如同串行执行的一样(为了解决脏读、不可重复读、幻读)
官方定义:
两阶段锁协议是指所有事务必须分两个阶段对数据加锁和解锁,在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁 。
对应到 MySQL 上分为两个阶段:
但是两阶段锁协议不要求事务必须一次将所有需要使用的数据加锁(innodb在需要的索引列数据才锁行),并且在加锁阶段没有顺序要求,所以这种并发控制方式会形成死锁 。
MySQL有两种死锁处理方式:
死锁检测 (默认开启)
死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁 。
回滚
检测到死锁之后 , 选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断 。
收集死锁信息:
减少死锁:
死锁解决: