在本文中,我们将讨论事务、死锁的概述,并将重点关注更新与并发更新的冲突,并通过示例进行理解。让我们一一讨论。
交易:
事务是一个逻辑工作单元,可以有一个或多个 SQL 语句。事务在您提交或完全回滚时结束。
死锁:
当多个进程所需的资源上持有排它锁并且这些进程无法继续完成时,就会发生死锁。
死锁和更新与并发更新冲突:
“死锁更新与并发更新冲突”异常发生在多个事务要同时修改同一行(或另一个事务提交之前的不同时间)时。只有一个更新程序可以真正更改行并提交。只要第一个事务尚未提交,第二个 /other 事务中的更新就会等待(无限期或直到配置的超时)。一旦第一个事务提交,第二个事务中的更新就会以这个错误结束 注意:如果第一个事务回滚了,第二个事务会继续,因为事务 1 完成的更新被回滚了。
避免死锁:
为了避免死锁,即避免多个进程在一个资源(此处为 Row)上持有锁,firebird 引发了这种异常。现在让我们看一个例子来清楚地理解这种问题如下。
例子 –
在这里,我们将通过一个例子来理解这个概念。
- 假设我们已经在数据库“Test1.fdb”中创建了一个名为“Emp”的表,它保存了员工的 ID 和员工的姓名。表数据如下。
ID | NAME |
---|---|
100 | Rita |
20 | John |
3 | Albert |
- 让我们假设我们有 2 个事务:Trans1 和 Trans2。 Trans1 在时间 t1 开始,Trans2 在时间 t2 开始。现在两者都想更新同一行,即名称 = ‘John’ 的行。
- 事务 Trans1 在 t3 时间开始更新。在 Trans1 提交之前,Transaction 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 工具窗口并在 1 个窗口上运行 Trans1,在另一个窗口上运行 Trans2。
- 在上面的窗口中,在 Trans1 中,您还没有提交。
- 在你提交 Trans1 之后,错误信息 – “deadlock;更新与并发更新冲突”将显示在 Trans2 窗口中。
为避免此类错误消息:
要么在事务 Trans1 中回滚,要么仅在 Trsan1 提交时在 Trans2 中的同一行上开始更新。