死锁问题和并发问题
如果没有锁就不存在死锁问题。
因此死锁问题是并发问题的衍生问题,因为要解决并发问题,就设计了锁这个解决方案,因为要用锁这个解决方案,就有可能弄不好产生死锁问题。
死锁是个什么概念?
假设现在有P1和P2两个人:
如果资源只有1个a,那么除非P1手握a不放,才会造成P2的死锁。
如果资源有a和b,那么P1持有a,P2持有b,P1想要b,P2想要a,此时两个人都要对方手上的,又不释放自己手上的资源,就会造成死锁。
解决方法也很简单:
1、timeout时间,任何资源不允许任何人长期持有
2、在编码时,注意出现彼此需要对方资源的情况
3、尽量避免同时锁定多个资源的情况
举例看锁问题:
数据库的内容被修改时,会锁住。如果事务中修改了a表,又修改了b表。
事务1先修改a表,再修改b表,
事务2先修改b表,再修改a表,
就会造成争抢,a和b表都会被锁表。
有一种通过标记来加锁的方式,如果标记了加锁,又没有取消锁的话,就会让代码人为一直处于锁定状态。
总之,死锁问题都是因为程序员不小心导致的。最佳的办法当然是在框架级别隔离锁,让业务程序员不用考虑锁的问题。
底线方案:
1、锁过期:给每个锁加上时间,超时则自动释放。
2、锁监视器:发现死锁,自动释放一条低优先级链路的锁,确保另一条可以继续执行
3、人工处理
操作数据库的程序避免死锁的方法:
1、select不要放入事务中
2、降低事务隔离级别
3、使用行锁
4、绑定连接?
数据库锁:
1、共享锁:读锁,所有线程只可以读,不可写
2、更新锁:其他线程可以读,当前线程可以读写
3、排他锁:写锁,其他线程不可读写,当前线程可以读写
数据库有一些命令可以看到哪些内容被锁住了,可以强制关闭锁。kill spid
SET LOCK_TIMEOUT timeout_period 设定锁请求超时
尽可能用行锁而不是表锁
image.png