【发布时间】:2015-06-13 14:29:45
【问题描述】:
我有以下(简化的)Hibernate 实体:
@Entity(name = "Foo")
public class Foo {
@Id
@GeneratedValue
public int id;
@OneToOne
public Bar bar;
}
和,
@Entity(name = "Bar")
public class Bar {
@Id
@GeneratedValue
public int id;
@Column
public String field;
@Version
public int version;
}
我在一个大致如下所示的事务中更新这些实体:
Bar bar = findBar(em);
Foo foo = findFoo(em);
bar.field = "updated value";
if (<condition>) {
em.remove(foo);
}
em.detach(bar);
em.merge(bar);
请注意,em.remove(foo) 只是有时会被调用,而 bar 总是会更新。
我注意到运行应用程序时偶尔出现ORA-00060: Deadlock detected 错误。转储似乎表明两个死锁会话被锁定在 em.merge(bar) 和 em.remove(foo),但我不明白为什么会这样。
这段代码怎么会死锁?有没有办法对其进行重组以避免死锁?
以下是跟踪中的一些额外信息:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-00040005-000010dd 73 6557 X 81 6498 X
TX-00010018-000010bd 81 6498 X 73 6557 X
session 6557: DID 0001-0049-000002F5 session 6498: DID 0001-0051-0000030E
session 6498: DID 0001-0051-0000030E session 6557: DID 0001-0049-000002F5
Rows waited on:
Session 6557: obj - rowid = 00004797 - AAAEeXAB4AAADH0BBP
(dictionary objn - 18331, file - 120, block - 12788, slot - 15)
Session 6498: obj - rowid = 00007191 - AAAHGRAB4AAAACBBBo
(dictionary objn - 29041, file - 120, block - 129, slot - 40)
----- Information for the OTHER waiting sessions -----
Session 6498:
program: JDBC Thin Client
application name: JDBC Thin Client, hash value=2546894660
current SQL:
delete from Foo where id=:1
----- Current SQL Statement for this session (sql_id=sfasdgasdgaf) -----
update Bar set field=:1, version=:2 where id=:3 and version=:4
【问题讨论】:
-
也许真的不可能重现您的问题。如果它对你有帮助,请看这个lalitkumarb.wordpress.com/2014/02/25/…
-
您是否可以跟踪完整的会话?
-
@LalitKumarB 我有跟踪,从那里我将其追溯到那些合并和删除的调用。我看到那是两个锁定的会话。您想从跟踪中获得任何其他信息吗?
标签: java oracle hibernate jpa transactions