在本文中,我们将讨论事务,死锁的概述,并将重点放在与并发更新发生的更新冲突上,并借助示例进行理解。让我们一一讨论。
交易:
事务是一个逻辑工作单元,可以包含一个或多个SQL语句。当您提交或完全回滚事务时,事务结束。
死锁:
当对多个进程所需的资源持有排他锁并且这些进程无法继续完成时,就会发生死锁。
死锁和更新与并发更新冲突:
当多个事务要同时(或在另一个提交之前的不同时间)修改同一行时,将发生“死锁更新与并发更新冲突”异常。只有一个更新程序才能真正更改行并提交。只要第一个事务尚未提交,第二个/ other事务中的更新将等待(无限期或直到配置的超时)。第一个事务提交后,第二个事务中的更新将以此错误结束。注意:如果相反,第一个事务已回滚,则第二个事务将继续,因为由transaction1完成的更新已回滚。
避免死锁:
为了避免死锁,即避免锁被多个进程保留在资源上(此处为行),firebird会引发这种异常。现在让我们看一个例子,以清楚地理解这种问题,如下所示。
例子 –
在这里,我们将借助示例来理解该概念。
- 假设我们已经在数据库“ Test1.fdb”中创建了一个表名称“ Emp”,该表保留了雇员的ID和雇员的名称。表数据如下。
ID | NAME |
---|---|
100 | Rita |
20 | John |
3 | Albert |
- 让我们假设我们有2个事务:Trans1和Trans2。 Trans1在时间t1开始,而Trans2在时间t2开始。现在,两者都希望更新同一行,即name =’John’的行。
- 事务Trans1在t3时间开始更新。在Trans1提交之前,事务Trans2尝试更新由Trans1更新的同一行。因此Trans2进入等待状态,等待Trans1提交或回滚。
- 请参阅时间轴图以更清楚地了解它,如下所示。
Time | Trans1 | Trans2 |
---|---|---|
t1 | Start | |
t2 | Start | |
t3 | Update row having name = John | |
t4 | Update row having name = John | |
t5 | Commit | Update conflict |
笔记 :
- 如果Trans1提交-Trans2退出等待状态和错误消息-“死锁;将显示“与并发更新冲突”。
- 如果Trans1 ROLLBACK-Trans2退出等待状态,并且可以在同一行上完成更新。
- 要进行检查,请打开2个firebird ISQL Tool窗口,并在1个窗口上运行Trans1,在另一个窗口上运行Trans2。
- 在上面的窗口中,在Trans1中,您尚未提交。
- 提交Trans1后,错误消息–“死锁; “更新与并发更新冲突”将显示在Trans2窗口中。
为了避免这种错误消息:
在事务Trans1中回滚,或者仅在Trsan1提交时才在Trans2的同一行上开始更新。