线程死锁问题

Theads deadlock issue

环境:

  Wildfly 8.1
  Struts
  EJB 3.1
  Postgres 9

面临线程死锁问题。希望得到一些澄清。

代码:

 bean.writeLockedUpdate(o1) #1
 ...
 bean.writeLockedUpdate(o1) #2

场景:

两个用户线程都试图修改相同 o1 对象。

这两个线程的线程转储片段:

线程 1:

"default task-56" #558 prio=5 os_prio=0 tid=0x724a4400 nid=0x1674 waiting on condition [0x3d2ef000] java.lang.Thread.State: TIMED_WAITING (parking)
at org.jboss.as.ejb3.concurrency.EJBReadWriteLock$WriteLock.tryLock(EJBReadWriteLock.java:209)

at Bean$$$view22.writeLockedUpdate(Unknown Source)

线程 2:

"default task-43" #530 prio=5 os_prio=0 tid=0x6bf10800 nid=0x15aa runnable [0x299c8000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method)
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:143)

at Bean$$$view22.writeLockedUpdate(Unknown Source)

可能的解释:

我相信这就是正在发生的事情。

  1. thread2 已获取 bean 写锁,正在等待 DB 行锁
  2. thread1 已获取 DB 行锁,正在等待 bean 写锁

Jconsole 没有显示任何死锁。猜测是因为被阻止的第二个锁是在数据库级别

问题:

有没有办法验证上面的解释?

提前致谢。

从 Java 和 postgresql 数据库得到确认。

  1. 线程转储清楚地显示线程 1 正在等待 EJB 写锁

  2. 对 postgres 的以下查询揭示了被阻止的操作

select bl.pid as blocked_pid, bl.mode as blocked_mode, a.usename as blocked_user, ka.query as blocking_statement, now() - ka.query_start as blocking_duration, kl.pid as blocking_pid, kl.mode as blocking_mode, ka.usename as blocking_user, a.query as blocked_statement, now() - a.query_start as blocked_duration from pg_catalog.pg_locks bl join pg_catalog.pg_stat_activity a on bl.pid = a.pid join pg_catalog.pg_locks kl join pg_catalog.pg_stat_activity ka on kl.pid = ka.pid on bl.transactionid = kl.transactionid and bl.pid != kl.pid where not bl.granted

在我的例子中,上面的查询 returns 一行显示更新被阻止

谢谢, 拉凯什