解决僵局的策略?
Posted
技术标签:
【中文标题】解决僵局的策略?【英文标题】:Strategy to approach the deadlocks? 【发布时间】:2014-11-19 09:42:26 【问题描述】:我在生产中遇到了数据库死锁。在分析中,我发现两个线程以相反的顺序获取锁。 例如:-
1)Thread 1 :-
它首先获得表1行的排他行锁,然后尝试获取表2行的共享行锁。
2)Thread 2:-
它首先获得表2行的排他行锁,然后尝试获取表1行的共享行锁。
因此发生了死锁。
幸运的是,我能够在线程 2 下通过以与线程 1 相同的顺序获取锁来解决它,即现在两个线程都试图获取 先在表 1 上加锁,然后在表 2 上加锁。这样死锁就解决了。
我很幸运在这里可以更改锁定顺序,因为它涉及较小的更改。但我确信在某些情况下 由于业务功能或可能需要对应用程序进行重大更改,这是不可能的。所以我可以考虑另外两种方式 解决这些死锁(无论是数据库锁还是java锁)。他们是:-
我能想到的另一种方式是
1) 悲观锁在哪里需要提前获取锁 资源
2) 在开始操作之前将可重入锁保存在缓存中 线程 1 和线程 2 无法继续,直到第一个线程释放 锁。但我不相信这种方法,因为它会填补 使用这种代码的应用程序。开发人员也可以忘记 释放锁。
所以我想知道解决死锁的其他替代方法是什么。有什么想法吗?
【问题讨论】:
【参考方案1】:您可以在数据库中创建表(locktable)并将锁定记录的主键存储在该表中。 在更新主表之前尝试在 locktable 中查找记录。 如果没有找到记录,您将在 locktable 中创建并选择更新记录。 其他线程和应用程序在更新主表之前检查 locktable 中的记录。这种方式的好处 - 您的应用程序不会锁定主表中的数据,其他进程可能会从主表中选择数据。
如何确保对这张表的可序列化访问?
所有应用程序都插入锁定记录并锁定悲观(选择更新)此记录。
【讨论】:
似乎是个好主意,但是如何保证对这张表的可序列化访问呢?以上是关于解决僵局的策略?的主要内容,如果未能解决你的问题,请参考以下文章
:进程管理 -- 死锁的概念死锁饥饿死循环的区别死锁的处理策略(预防 / 避免死锁 / 死锁的检测和解除)SPOOLing技术银行家算法