锁的相关知识又跟存储引擎,索引,事务的隔离级别都是关联的....
这就给初学数据库锁的人带来不少的麻烦~~~于是我下面就简单整理一下数据库锁的知识点,希望大家看完会有所帮助 。
1、为什么需要学习数据库锁知识
不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下)
一般也就听过常说的乐观锁和悲观锁,了解过基本的含义之后就没了~~~
定心丸:即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的 。因为这些锁数据库隐式帮我们加了:
- 对于UPDATE、DELETE、INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);
- MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预;
- 能让我们在特定的场景下派得上用场
- 更好把控自己写的程序
- 在跟别人聊数据库技术的时候可以搭上几句话
- 构建自己的知识库体系!在面试的时候不虚
首先,从锁的粒度,我们可以分成两大类:
- 表锁开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低;
- 行锁开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高;
- InnoDB行锁和表锁都支持!
- MyISAM只支持表锁!
- 也就是说,InnoDB的行锁是基于索引的!
- 表读锁(Table Read Lock)
- 表写锁(Table Write Lock)
- 从下图可以清晰看到,在表读锁和表写锁的环境下:读读不阻塞,读写阻塞,写写阻塞!
- 读读不阻塞:当前用户在读数据,其他的用户也在读数据,不会加锁
- 读写阻塞:当前用户在读数据,其他的用户不能修改当前用户读的数据,会加锁!
- 写写阻塞:当前用户在修改数据,其他的用户不能修改当前用户正在修改的数据,会加锁!
文章插图
从上面已经看到了:读锁和写锁是互斥的,读写操作是串行 。
- 如果某个进程想要获取读锁,同时另外一个进程想要获取写锁 。在mysql里边,写锁是优先于读锁的!
- 写锁和读锁优先级的问题是可以通过参数调节的:max_write_lock_count和low-priority-updates
文章插图
- MyISAM可以支持查询和插入操作的并发进行 。可以通过系统变量concurrent_insert来指定哪种模式,在MyISAM中它默认是:如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录 。
- 但是InnoDB存储引擎是不支持的!
无论是Read committed还是Repeatable read隔离级别,都是为了解决读写冲突的问题 。
单纯在Repeatable read隔离级别下我们来考虑一个问题:
文章插图
此时,用户李四的操作就丢失掉了:
- 丢失更新:一个事务的更新覆盖了其它事务的更新结果 。
解决的方法:
- 使用Serializable隔离级别,事务是串行执行的!
- 乐观锁
- 悲观锁
- 乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段 。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样 。如果一样更新,反之拒绝 。之所以叫乐观,因为这个模式没有从数据库加锁,等到更新的时候再判断是否可以更新 。
- 悲观锁是数据库层面加锁,都会阻塞去等待锁 。
所以,按照上面的例子 。我们使用悲观锁的话其实很简单(手动加行锁就行了):
推荐阅读
- 数据库缓存更新的套路
- html5怎么连接数据库?
- 数据库并发2万就跪了?你需要这份指导性的知识框架
- 优化必备 redis异步访问模式--管道技术
- 北京大医院看病有窍门,真的!挂号一定要认准“两大四小”
- 从拍照到视频,这9款摄影后期APP“装机必备”
- 超全的出境必备APP清单,就算不会英语毫无方向感,也能走遍全球
- Python 连接数据库的多种方法
- 4个MySQL优化工具AWR,帮你准确定位数据库瓶颈!
- mysql怎么导出数据库?