在多个并行线程中从 table 中删除时的 JPA 死锁
JPA Deadlock when delete from a table in several parallel threads
我有几个线程,具有不同的事务和实体管理器,它们必须刷新对象的事件。要刷新这些事件,首先我 删除旧的,然后保留 新的。用一个线程它工作得很好,但是用多个它在删除事件时发生死锁。
所有线程正在删除不同的对象,有时,在不同的 table 中。那么为什么会发生这种资源竞争呢? 我正在使用主键 JPA 阻止正确的对象。我查看是否还有其他代码也在使用该资源,但没有找到。 JPA 是否锁定整个 table 而不是行?
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 ))
我解决了这个错误。
我有两个具有双向@OneToOne 关系 的 JPA 实体。当我调用 EntityManager.remove() 时,我没有传递关系的所有者 。这使 Oracle 抛出 DeadLockException。
这样,EclipseLink 在要删除的同一实体上创建了两个语句。
这对我来说似乎是一个错误,JPA 实现应该处理这个问题。
我有几个线程,具有不同的事务和实体管理器,它们必须刷新对象的事件。要刷新这些事件,首先我 删除旧的,然后保留 新的。用一个线程它工作得很好,但是用多个它在删除事件时发生死锁。
所有线程正在删除不同的对象,有时,在不同的 table 中。那么为什么会发生这种资源竞争呢? 我正在使用主键 JPA 阻止正确的对象。我查看是否还有其他代码也在使用该资源,但没有找到。 JPA 是否锁定整个 table 而不是行?
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 ))
我解决了这个错误。
我有两个具有双向@OneToOne 关系 的 JPA 实体。当我调用 EntityManager.remove() 时,我没有传递关系的所有者 。这使 Oracle 抛出 DeadLockException。
这样,EclipseLink 在要删除的同一实体上创建了两个语句。 这对我来说似乎是一个错误,JPA 实现应该处理这个问题。