【发布时间】:2023-03-12 14:57:01
【问题描述】:
我有几个线程,具有不同的事务和实体管理器,它们必须刷新对象的事件。要刷新这些事件,首先我删除旧的,然后持久化新的。一个线程运行良好,但多个线程在删除事件时会发生死锁。
所有线程都在删除不同的对象,有时是在不同的表中。那么为什么会发生这种对资源的竞争呢? 我正在使用主键来 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 ))
【问题讨论】:
-
Oracle 应该在服务器上创建一个跟踪文件,详细说明发生死锁的原因。您操作的表格不止一张吗?在您的交易中?
-
@OldProgrammer 实际上从两个表中删除。一对一的关系。但是当我删除这两个关联实体时,正在读取主实体。所以总共三个表,主和两个关联。
-
去阅读this。
-
@OldProgrammer 非常感谢您提供本文。我已经知道什么是死锁,我会试着弄清楚发生了什么。我确定我做错了。这段代码不是开源的,否则我会把它分享给 Stackoverflow。
-
因为您在交易中不知何故存在交叉依赖关系。您对表有任何级联删除吗?下次发生时,跟踪文件会显示 rowid。使用它来查询它是哪一行并查看记录。这不是通过 cmets 可以通过 SO 解决的问题。对不起。不过,您走在正确的道路上。祝你好运
标签: java oracle jpa oracle11g database-deadlocks