• 分类

    • 读锁(共享锁):对同一个数据,多个读操作可以同时进行,互不干扰
    • 写锁(互斥锁):如果当前写操作没有完毕,则无法进行其他的读操作、写操作
  • 操作范围
    • 表锁:一次性对一张表整体加锁。如myisam存储使用引擎,开销小,加锁快,无死锁;锁的范围大,容易发生锁冲突,并发低
    • 行锁:一次性对一条数据加锁。如innodb使用行锁,开销大,加锁满,容易死锁;锁的范围小,不易发生锁冲突,并发度高(很小概率,发生高并发问题、不可重复读,丢失更新等问题)
      • 间隙锁(next-key):值在范围内,但却不存在

此时表中没有id=7的数据

update linelock set name = 'x' wher id > 1 and id < 9;

加锁 lock table 表1 read/write,表2 read/write

查看加锁的表: show open tables;

1.加读锁

结论1:一个会话,对A表加了read锁,则该会话可以对A表进行读操作,不能进行写操作;且该会话不能对其他表进行读、写操作。(即如果给A表加了读锁,则当前会话只能对A表进行读操作)

结论2:会话0对A表加了锁,其他会话的操作:

  • 可以对其他表(A表以外的表)进行读、写操作
  • 对A表可以读,写-需要等待释放锁 unlocal tables;

2.加写锁

会话0: lock table tablename write;

总结1:当前会话可以对加了写锁的表,可以进行任何操作(增删改查);但是不能操作(增删改查)其他表.

总结2:对会话0加写锁的表,可以进行增删改查的前提是:等会话0释放写锁。

3.行锁分析

  1. 如果会话x对某条数据a进行DML操作(研究时,关闭了自动commit的情况下),则其他会话必须等待会话x结束事务(commit/rollback)后,才能对数据a进行DML操作
  2. 表锁是通过 unlock tables; ,也可以通过事务解锁,行锁是通过事务解锁。
  3. 如果没有索引/索引失效,则行锁会转为表锁
  4. 行锁:如果有where,则实际加锁的范围就是where后面的范围(不是实际的值 )

    show status like '%innodb_row_lock%';

  • innodb_row_lock_current_waits; 当前正在等待锁的数量
  • innodb_row_lock_time; 等待总时长。从系统启动到现在一共等待的时间
  • innodb_row_lock_time_avg; 平均等待时长

如果发现锁争用比较严重,如InnoDB_row_lock_waitsInnoDB_row_lock_time_avg的值比较高

如果仅仅是查询数据,能否加锁?可以 for update:select * from linelock where id = 2 for update;

4.InnoDB锁问题

参考博客:https://www.cnblogs.com/jpfss/p/8890250.html

InnoDB和MyISAM最大不同有两点:一是支持事务;二是采用了行级锁

  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
  • 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。另外,为了允许行锁和表锁共存,实现多粒度锁机制

InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。

  • 意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
  • 意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

如果一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。

意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁;事务可以通过以下语句显示给记录集加共享锁或排他锁。

  • 共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。
  • 排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE。

用SELECT ... IN SHARE MODE获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT... FOR UPDATE方式获得排他锁。

5.InnoDB行锁实现方式

:通过索引上的索引项加锁来实现的。这种行锁特定意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

最新文章

  1. 洛谷P1372 又是毕业季I&amp;&amp;P1414 又是毕业季II[最大公约数]
  2. 学习SQL的点点滴滴(四)-UPDATE小计
  3. div高度自适应(父元素未知,所有高度跟随子元素最大的高度)
  4. EPANET中读取INPUT文件的函数文件——INPUT3.C
  5. [CareerCup] 9.9 Eight Queens 八皇后问题
  6. [LeetCode]题解(python):049-Groups Anagrams
  7. ios_图片放大的两种方式transform和frame
  8. hdu---(3779)Railroad(记忆化搜索/dfs)
  9. 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004
  10. java单链表代码实现
  11. GIT分支操作常用命令
  12. Copy-and-swap
  13. java虚拟机详解
  14. _.contains is not a function
  15. CAN总线基础知识(二)
  16. spring注解简单记录
  17. java中常规使用的mysql语句
  18. Python队列及在微信机器人中的应用
  19. 删掉centos原有的openjdk并安装sun jdk
  20. 基于easyui开发Web版Activiti流程定制器详解(六)——Draw2d的扩展(三)

热门文章

  1. iOS加载动态自定义字体
  2. js 秒转时分秒
  3. lua中定义变量用and和or连接
  4. JS篇(006)-怎样添加、移除、移动、复制、创建和查找节点?
  5. jeecg 自定义loading框(导入时加载备份/ajax请求加载loading)
  6. 什么是压测,为什么要进行压力测试?Jmeter工具的使用
  7. 半成品 java 身份证校验
  8. python——NLP关键词提取
  9. 浏览器输入URL发生了什么:DNS解析、TCP握手、HTTP缓存、重定向、服务器状态码、渲染引擎和JS引擎互斥、渲染过程、浏览器进程、网络进程、渲染进程
  10. ffmpeg编译错误/libfdk-aacenc.c: In function &#39;aac_encode_init&#39;