我收到了以下oracle日志:
DEADLOCK DETECTED ( ORA-00060 )
[Transaction Deadlock]
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-00120007-0002acbf 82 185 X 67 240 X
TX-0008001c-0009ed94 67 240 X 82 185 X
session 185: DID 0001-0052-00000004 session 240: DID 0001-0043-00000004
session 240: DID 0001-0043-00000004 session 185: DID 0001-0052-00000004
Rows waited on:
Session 185: obj - rowid = 0001285C - AAAShcAAiAAEoVFAAi
(dictionary objn - 75868, file - 34, block - 1213765, slot - 34)
Session 240: obj - rowid = 0001285C - AAAShcAAiAAEoRWAA3
(dictionary objn - 75868, file - 34, block - 1213526, slot - 55)
----- Information for the OTHER waiting sessions -----
Session 240:
sid: 240 ser: 7 audsid: 32762787 user: 76/NETCRACKER1
flags: (0x8000041) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40008) -/-
pid: 67 O/S info: user: oracle, term: UNKNOWN, ospid: 26869908
image: oracle@opipodb1
client details:
O/S info: user: adipoas1, term: unknown, ospid: 1234
machine: opipoas1 program: JDBC Thin Client
application name: JDBC Thin Client, hash value=2546894660
current SQL:
select o.object_id
from nc_objects o,
(select object_id
from nc_objects
connect by prior object_id = parent_id
start with object_id = :a1
union
select object_id
from nc_references
where reference in (select object_id
from nc_objects
connect by prior object_id = parent_id
start with object_id = :a1)) ids
where o.object_id = ids.object_id
order by o.object_id
for update of o.object_id
----- End of information for the OTHER waiting sessions -----
Information for THIS session:
----- Current SQL Statement for this session (sql_id=3mxkkzhttwa2q) -----
select o.object_id
from nc_objects o,
(select object_id
from nc_objects
connect by prior object_id = parent_id
start with object_id = :a1
union
select object_id
from nc_references
where reference in (select object_id
from nc_objects
connect by prior object_id = parent_id
start with object_id = :a1)) ids
where o.object_id = ids.object_id
order by o.object_id
for update of o.object_id
===================================================
是否意味着两个相等的查询(但可能有不同的数据)相互锁定?
如果是这样,怎么会发生? - 这个查询锁定有序序列,我想我们不能在这里遇到死锁。
DB是元模型 object_id - PK
由于
答案 0 :(得分:4)
ORDER BY will not always prevent deadlocks
这是一种可能导致查询死锁的情况:
:id=A
:id=B
:id=B
运行您的查询,会话1现在正在等待会话2 :id=A
运行您的查询,发出死锁当您发出SELECT FOR UPDATE
时,您将面临等待其他会话的风险。如果此会话已在等待您,则会出现死锁。
避免OLTP环境中死锁的一种常见方法是仅发出SELECT FOR UPDATE NOWAIT
。让第二个会话失败而不是等待。
您有多个会话更新同一个表。你有可能互相阻挡。如果你让他们等待并且他们更新了多行,你就有机会陷入僵局。您有很多选择来管理它:
让会话陷入僵局。 Oracle将自动检测到这一点并回滚一个。 Oracle will only rollback the last statement of one of the session, not the whole transaction,这意味着获取错误的会话应先回滚,然后再重试。
按照我的建议,用NOWAIT运行它们。
如果您不想让它们失败,您可以:
您需要回滚以确保两个会话无法无限制地相互阻止。
序列化更新。这通常通过确保只有一个会话可以同时更新表(或一系列行)来完成。
例如,您可以让所有会话INSERT在事务表中,并让单个作业将修改合并到最终表中。并发会话无法阻止彼此。这显然会将更新推迟到主表(至少在提交之后)。
我不建议选项1,因为你无法控制死锁检测(因此你无法对其进行优化)。