mysql提供了两种锁,一种使用select for update,一种mysql函数get_lock(str,timeout)。下面是我对其使用和一些肤浅的领悟:
首先是select for update,特别说明,mysql现在依旧不支持 select for update no wait。。。
测试环境如下:
==========================
数据库版本:
======================================
表结构(word_mood)
============================================================================================================================================
引擎:
下面开始介绍其使用和应该注意事项:
大家请注意查看上图显示的引擎是innodb为默认,故我要测试使用的也就是InnoDB。从我勾选出来的可以看出,它支持事物,行级锁,外键。什么是行级锁,我想大家应该都很明白,我们
再通过一些例子来加深影响。首先我会开两个console来演示:
=================================
A客户端对message_id=5的数据进行select for update操作,B客户端也对message_id=5的进行select for update操作,大家应该都已经猜到了结果,我们还是来验证下是否正确。
========================================================
大家请看上面的结果集,A客户端显示出message_id=5的结果,而B客户端在等待一段时间出现获取锁超时。说明for update具有锁表的功能,A客户端一直持有锁,并没有释放(事务没有提交),故B客户端在一定时间没有获取到锁则抛出了timeout异常。那么我们继续研究,此时是锁表还是锁行。
我会对message_id=1的数据for update。若是锁表此时,应该继续超时,若是锁行,则会显示出结果。大家请看下面:
大家请看,此时我们查询出message_id=1的结果,说明当where条件是主键的时候for update是进行锁行的,那么当where条件不存在主键是锁表还是锁行呢。
我们继续来验证,此时我会对A客户端message_content=0的数据进行for update,B客户端message_content=1的数据for update。在这之前,我会把这两个客户端的事务commit,然后重新开启事务
。
========================================================================
大家看上图,发现客户端B结果是empty set,说明A客户端执行的for update锁住word_mood这张表了。这也说明了当我们执行for update的时候若where条件是表的主键那么将只是锁住查询的那一行的数据,而不存在主键则是锁住整张表。那么又有同学会问,既然for update是锁行,能否对其他行进行操作呢?我将通过下面的试验展示给大家,在这之前我会commit掉A,B客户端,重新开启事务.
====================================================================
在上面的例子中我对A客户端的message_id=0数据进行了for update操作,然后在B客户端对message_id=5的数据进行了update,然后在insert了一条数据,均成功。说明我们锁住的只是当前行的update操作,而对其行没有影响。
现在我们再来看看get_lock(str,timeout)这个函数,这是mysql提供的,我们可以在开发中利用这个函数来堵塞线程。使用起来简单,但是坑也还是有的,只要明白了这个坑我们就可以在开发中避免。
我们先来说说这个函数的两个参数。第一个参数代表是要锁的字符串,第二个参数代表的是获取锁等待的时间。当返回值是1代表成功,0没有获取到值,null代表超时现在我就来演示如何使用,此时我会开两个console
=====================================
在上图中我首先用A客户端获取了一个lock锁,然后B客户端再去获取的时候,返回值为0。
既然有获取那么就有释放,函数release_lock(str)。参数代表要释放的锁;返回值:1成功,0,失败。
在下面的试验中,我会在A客户端释放锁(lock),B客户端继续获取锁
====================
我们发现当A释放掉时,B才能获取到锁。这是正常释放和获取锁的方式。既然有正常那就有异常了,在此我希望大家能记住这个异常。。。因为在开发中我们一定要避免这个异常,否则会出现不可控的情况。下面我们就来试验下这个异常。
大家请看上图,我首先获取了一个lockA这个锁,然后使用is_free_lock函数(返回1-空闲;0-正在使用)查看锁的使用情况,发现正在使用,结果正常。然后在获取锁lockB,然后使用is_free_lock函数再次查看lockA的使用情况,发现其使用状态变成了空闲。而lockB处于正在使用。并没有出现lockA,lockB都处于正在使用状态,大家可以理解为,当我们再次lock一个新的字符串的时候,mysql就会把以前存在的锁释放掉,然后再获取当前这个新的锁。所以我们在开发的时候尽量使用常量并且必须调用release释放锁
相关推荐
说说什么是最左匹配? 如何优化慢查询?(explain命令) 分库分表如何选择分表键 分库分表的情况下,查询时一般是如何做排序的? mysql分库分表,水平拆分和垂直拆分,水平拆分后如何路由 MySQL 索引使用的注意事项 ...
本资源摘要信息涵盖了 MySQL 数据库的基础知识、架构、存储引擎、索引、事务、锁、查询优化等方面的知识点。 数据库三范式 数据库三范式是数据库设计的基本原则,主要包括: 1. 强调属性的原子性约束,要求属性...
通过水平分表可以将数据分散存储,避免单表数据量过大导致的性能问题,如IO争抢和锁表的几率。水平分表能够有效地提升查询效率,尤其是在数据分布均匀的情况下效果更佳。然而,水平分表依然存在单表数据量过大的问题...
6. InnoDB 支持表、行级锁,而 MyISAM 支持表级锁。 7. InnoDB 表必须有主键,而 MyISAM 可以没有主键 8. InnoDB 表需要更多的内存和存储,而 MyISAM 可被压缩,存储空间较小。 9. InnoDB 按主键大小有序插入,...
6. InnoDB支持表、行级锁,而MyISAM支持表级锁 7. InnoDB表必须有主键,而MyISAM可以没有主键 8. InnoDB表需要更多的内存和存储,而MyISAM可被压缩,存储空间较小 9. InnoDB存储引擎提供了具有提交、回滚、崩溃恢复...
在MySQL中,如果表被锁定,通常需要分析并解决导致锁的问题,而不是直接解锁。 了解并熟练掌握这些查询语句,将有助于数据库管理员高效地管理和维护数据库,确保系统的稳定运行和数据的安全性。通过学习《查询表...
上百节课详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程介绍: ...51_说说MySQL读写分离的原理?主从同步延时咋解决? 52_如何设计高可用系统架构?限流?熔断?降级?什么鬼!
Java面试高级篇—说说TCP,UDP和socket,Http之间联系和区别.doc MySQL千万级的大表要怎么优化(读写分离、水平拆分、垂直拆分).doc redis缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级.doc RPC (Remote ...
(3)使用 悲观锁 或 乐观锁机制;(4)调整事务的执行顺序;(5)使用死锁检测机制;(6)使用事务回滚机制。 11.3. 日常工作中你是怎么优化SQL的? 优化SQL可以通过以下步骤:(1)使用EXPLAIN语句分析SQL执行计划;(2)使用...
锁机制?实现维持map大小的LRU算法? volatile关键字?volatile修饰数组?修饰对象? 找两条链表公共节点? 如何判断循环链表? mysql索引?B+数搜索复杂度? mysql事务? 进程线程区别? 进程池? 进程几种状态?...
特别是MySQL,其InnoDB引擎的锁机制、MVCC(多版本并发控制)以及查询优化策略都是常考点。 除此之外,面试宝典可能还会涉及其他技术领域,如微服务、分布式计算、负载均衡、网络协议等。对于微服务,你需要了解...
说说你对Servlet的理解.mp4 │ Java面试题18.Servlet的生命周期.mp4 │ Java面试题19.forward和redirect的区别.mp4 │ Java面试题20.jsp和Servlet的相同点和不同点?.mp4 │ Java面试题21.内置对象和四大作用域和...
ConcurrentHashMap的锁是读锁还是写锁? 69 【集合】HashMap与HashTable的区别 71 【多线程】什么是线程安全与非线程安全 72 【多线程】多线程的实现方式Thread、Runnable、Callable 72 【多线程】实现Runnable接口...
#### 20、说说Redis哈希槽的概念? Redis集群通过哈希槽来实现数据的分区。共有16384个哈希槽,每个键根据其哈希值映射到一个特定的哈希槽。每个哈希槽被分配给集群中的一个节点。 #### 21、Redis集群的主从复制...