我在生产时遇到了数据库死锁。在anaylsis上,我发现两个线程以相反的顺序进行锁定。 例如: -
1)Thread 1 :-
它首先在表1行上获得了独占行锁,然后尝试获取表2行上的共享行锁。
2)Thread 2:-
它首先在表2行上获得了独占行锁,然后尝试获取表1行上的共享行锁。
因此发生死锁。
幸运的是,我能够在线程2下通过以与线程1中相同的顺序获取锁来解决它,即现在两个线程都试图获取 首先锁定在表1上,然后锁定在表2上。所以死锁已经解决了。
我很幸运,这里可以改变锁定顺序,因为它涉及微小的变化。但我确信在某些情况下 由于业务功能或可能需要对应用程序进行重大更改,因此无法实现。所以我可以想到另外两种方式 解决这些死锁(无论是数据库锁还是java锁)。他们是: -
我能想到的另一种方式是
1)悲观锁定在必要时提前获取锁定的位置 resorces
2)在开始操作之前将重入锁保持在缓存中 线程1和线程2无法继续,直到第一个线程释放 锁。但我不相信这种方法,因为它将填补 使用这种代码的应用程序。开发人员也可以忘记 解锁。
所以我想知道解决死锁的其他替代方法是什么。有什么想法吗?
答案 0 :(得分:0)
您可以在数据库中创建表(locktable)并将锁定记录的主键存储在此表中
在更新主表之前尝试在locktable中查找记录。
如果未找到任何记录,您将在锁定表中创建并选择更新记录。
其他线程和应用程序在更新主表之前检查锁定表中的记录。
这种方式的奖励 - 您的应用程序不会锁定主表中的数据,其他进程可以从主表中选择数据。 / p>
如何确保对此表的可序列化访问?
所有应用程序都会插入lockrecords并锁定悲观(make select for update)此记录。