从几个并行线程中的表中删除时出现JPA死锁

时间:2015-08-01 12:56:03

标签: java oracle jpa oracle11g database-deadlocks

我有多个主题,具有不同的Transactions和EntityManagers,必须刷新对象的事件。要刷新这些事件,首先我删除旧的>新的。使用一个线程它可以正常工作,但有几个线程在删除事件时会发生死锁。

所有线程正在删除不同的对象,有时也会删除不同的表。那为什么这场资源竞争会发生呢? 我正在使用主键来JPA阻止正确的对象。我查看是否有其他代码也使用该资源,但我没有找到它。 JPA是锁定整个表而不是行吗?

Exception in thread "Thread-4" javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-00060: deadlock detected while waiting for resource

Error Code: 60
Call: DELETE FROM event WHERE ((id = ?) AND (version = ?))
    bind => [426687, 1]
Query: DeleteObjectQuery(Event[id=426687,tipo=BDE,status=1,data=java.util.GregorianCalendar[time=1431489600000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTim         

这是OOracle跟踪文件。

*** 2015-07-05 15:21:02.351
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
TM-00007874-00000000        44      29    SX             51     185    SX   SSX
TX-00020021-00000a5f        51     185     X             44      29           X

session 29: DID 0001-002C-0000000D      session 185: DID 0001-0033-00000004
session 185: DID 0001-0033-00000004     session 29: DID 0001-002C-0000000D

Rows waited on:
  Session 29: obj - rowid = 00007874 - AAAHh0AABAAAO2fAAX
  (dictionary objn - 30836, file - 1, block - 60831, slot - 23)
  Session 185: no row

----- Information for the OTHER waiting sessions -----
Session 185:
  sid: 185 ser: 3883 audsid: 422763 user: 55/LUPAZUL_DEV
    flags: (0x41) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
    flags2: (0x40009) -/-
  pid: 51 O/S info: user: oracle, term: UNKNOWN, ospid: 9977
    image: oracle@sydney-oracle11gexpress
  client details:
    O/S info: user: Pickler, term: unknown, ospid: 1234
    machine: MacBook program: JDBC Thin Client
    application name: JDBC Thin Client, hash value=2546894660
  current SQL:
  DELETE FROM correios_event WHERE ((id = :1 ) AND (version = :2 ))

----- End of information for the OTHER waiting sessions -----

Information for THIS session:

----- Current SQL Statement for this session (sql_id=fcrp8hfyatd79) -----
DELETE FROM correios_destiny WHERE ((id = :1 ) AND (version = :2 ))

1 个答案:

答案 0 :(得分:2)

我解决了这个错误。

我有两个双向@OneToOne关系的JPA实体。当我调用EntityManager.remove()时,我没有通过关系的所有者。这使得Oracle抛出了DeadLockException。

这样EclipseLink就要删除的同一个实体创建了两个语句。 这对我来说似乎是一个bug,JPA实现应该处理这个问题。