Eclipselink OptimisticLock导致死锁

时间:2014-08-17 15:03:17

标签: jpa eclipselink deadlock

我们使用eclipselink作为deafult JPA提供程序在WL 12c上运行企业应用程序。 MS SQL Server 2008是后端数据库 我有一个实体使用了以下定义。该实体与其他实体没有任何关系

@Entity 
@Table(name="TCALCNX") 
@Cache(isolation=CacheIsolationType.ISOLATED, expiry=0, alwaysRefresh=true) 
@OptimisticLocking(type=OptimisticLockingType.SELECTED_COLUMNS, selectedColumns=   {@Column(name="REC_UDT_TS")}) 

正如您所看到的,对所选字段存在乐观锁定,这意味着所有用户都可以读取实体 更新实体时,会进行检查以确保对象在读取后没有更改。如果是,我们会得到乐观锁定异常。

在我的情况下发生的事情是当我使用optimisticlock运行应用程序时,我很少得到optmisticlock异常但是死锁异常数量很多。 如果我在关闭乐观锁的情况下运行应用程序,则不会出现任何死锁异常。

 Internal Exception: java.sql.SQLTransactionRollbackException: [FMWGEN][SQLServer 
  JDBC     Driver][SQLServer]Transaction (Process ID 338) was deadlocked on lock 
 | communication buffer resources with another process and has been chosen as the 
  deadlock victim. Rerun the transaction.
 Error Code: 1205

乐观锁与死锁有什么关系

  1. 好的,假设有两个事务读取对象并对其进行了修改。两个交易都在同时更新。 如果是这种情况,那么我会在关闭乐观锁的情况下获得死锁异常。但我没有得到 关闭optimisticlock时的任何死锁异常。

  2. 当我打开乐观锁时,看起来有很多并发导致死锁

  3. 如果启用了optimsticlock,则不会对更新进行排序,从而导致大量并发

    有没有办法确定ecliselink中是否订购了交易

    后端数据库隔离级别为read_committed。

    请不要犹豫发表任何评论,可以从任何方面找到线索,我可以从中得到答案

    实体

    @Entity 
    @Table(name="TCALCNX")
    @Cache(isolation=CacheIsolationType.ISOLATED, expiry=0, alwaysRefresh=true)
    @OptimisticLocking(type=OptimisticLockingType.SELECTED_COLUMNS,selectedColumns=  {@Column(name = "REC_UDT_TS")} )
     public class CallContentEntity implements Serializable {
    
    
    public static final String RECORDSTATUS_ADDED       = "01";
    public static final String RECORDSTATUS_UPDATED     = "02";
    public static final String RECORDSTATUS_MARKED_FOR_DELETION = "15";
    
    
    @Id
    @Column(name="CAL_ID_NR")
    private String CallID;
    
    @Column(name="CAL_CNX_B")
    private byte[] CallContent;
    
    @Column(name="REC_UDT_TS")
    private Timestamp UpdateTimestamp;
    
    @Column(name="REC_STS_CD", length=2)
    private String RecordStatusCode;
    
    @Column(name="SRC_DAT_CTR_NR", length=2)
    private String SourceDataCnterNum;
    
    @Column(name="REC_TYP_VER_NR", length=4)
    private String VersionNumber;
    
    @Column(name="REC_SEQ_NR")
    private int SequenceNumber;
    
    private static final long serialVersionUID = 1L;
    
    
    
    public CallContentEntity() {
        super();
    }
    
    public CallContentEntity(String callID) {
        super();
        LookUpValues lkup= LookUpValues.getInstance();
        setCallID(callID);
        setCallContent(null);
        setRecordStatusCode(RECORDSTATUS_ADDED);
        setUpdateTimestamp(new java.sql.Timestamp(Calendar.getInstance().getTimeInMillis()));
        String sdatacntr= Integer.toString(lkup.getEnvironmentValue());
        setSourceDataCnterNum(sdatacntr);
        setVersionNumber(lkup.getLookUpValue("callcontentversion"));
        setSequenceNumber(1);
    }   
    
    public String getCallID() {
        return this.CallID;
    }
    
    public void setCallID(String CallID) {
        this.CallID = CallID;
    }   
    public byte[] getCallContent() {
        return this.CallContent;
    }
    
    public void setCallContent(byte[] CallContent) {
        this.CallContent = CallContent;
    }   
    public Timestamp getUpdateTimestamp() {
        return this.UpdateTimestamp;
    }
    
    public void setUpdateTimestamp(Timestamp UpdateTimestamp) {
        this.UpdateTimestamp = UpdateTimestamp;
    }   
    public String getRecordStatusCode() {
        return this.RecordStatusCode;
    }
    
    public void setRecordStatusCode(String RecordStatusCode) {
        this.RecordStatusCode = RecordStatusCode;
    }
    
    public String getSourceDataCnterNum() {
        return SourceDataCnterNum;
    }
    
    public void setSourceDataCnterNum(String sourceDataCnterNum) {
        SourceDataCnterNum = sourceDataCnterNum;
    }
    
    public String getVersionNumber() {
        return VersionNumber;
    }
    
    public void setVersionNumber(String versionNumber) {
        VersionNumber = versionNumber;
    }
    
    public int getSequenceNumber() {
        return SequenceNumber;
    }
    
    public void setSequenceNumber(int sequenceNumber) {
        SequenceNumber = sequenceNumber;
    }
    

    异常

    Exception stack: 
    Local Exception Stack: 
    Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
    Internal Exception: java.sql.SQLTransactionRollbackException: [FMWGEN][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 338) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
    Error Code: 1205
    Call: SELECT CAL_ID_NR, CAL_CNX_B, REC_STS_CD, REC_SEQ_NR, SRC_DAT_CTR_NR, REC_UDT_TS, REC_TYP_VER_NR FROM TCALCNX WHERE (CAL_ID_NR = ?)
        bind => [P4F22420140806182408001244]
    Query: ReadObjectQuery(name="readObject" referenceClass=CallContentEntity sql="SELECT CAL_ID_NR, CAL_CNX_B, REC_STS_CD, REC_SEQ_NR, SRC_DAT_CTR_NR, REC_UDT_TS, REC_TYP_VER_NR FROM TCALCNX WHERE (CAL_ID_NR = ?)")
        at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:644)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
        at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
        at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:566)
        at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:207)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectOneRow(DatasourceCallQueryMechanism.java:666)
        at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectOneRowFromTable(ExpressionQueryMechanism.java:2656)
        at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectOneRow(ExpressionQueryMechanism.java:2627)
        at org.eclipse.persistence.queries.ReadObjectQuery.executeObjectLevelReadQuery(ReadObjectQuery.java:450)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
        at org.eclipse.persistence.queries.ReadObjectQuery.execute(ReadObjectQuery.java:418)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1449)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.executeQuery(EntityManagerImpl.java:820)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.findInternal(EntityManagerImpl.java:760)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:653)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:532)
        at sun.reflect.GeneratedMethodAccessor131.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at weblogic.persistence.BasePersistenceContextProxyImpl.invoke(BasePersistenceContextProxyImpl.java:111)
        at weblogic.persistence.TransactionalEntityManagerProxyImpl.invoke(TransactionalEntityManagerProxyImpl.java:82)
        at weblogic.persistence.BasePersistenceContextProxyImpl.invoke(BasePersistenceContextProxyImpl.java:92)
        at $Proxy99.find(Unknown Source)
        at com.ups.ivr.ins.ejb.CallContentSession.Lookup(CallContentSession.java:207)
        at com.ups.ivr.ins.ejb.CallContentSession_95sf62_CallContentSessionLocalImpl.__WL_invoke(Unknown Source)
        at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:31)
        at com.ups.ivr.ins.ejb.CallContentSession_95sf62_CallContentSessionLocalImpl.Lookup(Unknown Source)
        at com.ups.ivr.ins.ejb.CallManager.getCurrentCallContent(CallManager.java:402)
        at com.ups.ivr.ins.ejb.CallManager_11k7mo_CallManagerLocalImpl.__WL_invoke(Unknown Source)
        at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:31)
        at com.ups.ivr.ins.ejb.CallManager_11k7mo_CallManagerLocalImpl.getCurrentCallContent(Unknown Source)
        at com.ups.ivr.ins.ejb.LookupSessionBean.Processdata(LookupSessionBean.java:184)
        at com.ups.ivr.ins.ejb.LookupSessionBean_1i73wg_LookupSessionBeanLocalImpl.__WL_invoke(Unknown Source)
        at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:31)
        at com.ups.ivr.ins.ejb.LookupSessionBean_1i73wg_LookupSessionBeanLocalImpl.Processdata(Unknown Source)
        at com.ups.ivr.ins.mwproxy.ClientRequestProcessor.doPost(ClientRequestProcessor.java:140)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:751)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3292)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3262)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
        at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
        at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2171)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2097)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2075)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1514)
        at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
    Caused by: java.sql.SQLTransactionRollbackException: [FMWGEN][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 338) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
        at weblogic.jdbc.sqlserverbase.ddb_.b(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddb_.a(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddb9.b(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddb9.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.v(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddq.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.a(Unknown Source)
        at weblogic.jdbc.sqlserver.ddh.a(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddcq.k(Unknown Source)
        at weblogic.jdbc.sqlserverbase.dddm.next(Unknown Source)
        at weblogic.jdbc.wrapper.ResultSet_weblogic_jdbc_sqlserverbase_dddn.next(Unknown Source)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processResultSet(DatabaseAccessor.java:699)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:621)
        ... 62 more
    

    更新例外

    <2014-08-06> [P4F21420140806182553001248] <12:27:24,293> {ERROR} CallContentSession - CallContent Update Exception. 
     Failed to write Lookup content entry:(P4F21420140806182553001248)
    Exception stack: 
    weblogic.transaction.RollbackException: Unexpected exception in beforeCompletion: sync=org.eclipse.persistence.transaction.JTASynchronizationListener@1c1f9da7
    
    Internal Exception: java.sql.SQLTransactionRollbackException: [FMWGEN][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 338) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
    Error Code: 1205
    Call: UPDATE TCALCNX SET CAL_CNX_B = ?, REC_STS_CD = ?, REC_UDT_TS = ? WHERE ((CAL_ID_NR = ?) AND (REC_UDT_TS = ?))
        bind => [[B@1c1f9699, 02, 2014-08-06 12:27:22.645, P4F21420140806182553001248, 2014-08-06 12:27:21.287]
    Query: UpdateObjectQuery(CALL ID :P4F21420140806182553001248
    REC_UDT_TS :2014-08-06 12:27:22.645
    REC_STS_CD:02
    SRC_DT_CNTR:10
    VERSION_NUM :001
    REC_SEQ_NR:1)
        at weblogic.transaction.internal.TransactionImpl.throwRollbackException(TransactionImpl.java:1884)
        at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:376)
        at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:268)
        at weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:308)
        at weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:302)
        at com.ups.ivr.ins.ejb.CallContentSession.Update(CallContentSession.java:276)
        at com.ups.ivr.ins.ejb.CallContentSession_95sf62_CallContentSessionLocalImpl.__WL_invoke(Unknown Source)
        at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:31)
        at com.ups.ivr.ins.ejb.CallContentSession_95sf62_CallContentSessionLocalImpl.Update(Unknown Source)
        at com.ups.ivr.ins.ejb.CallManager.saveCall(CallManager.java:130)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.ups.ivr.ins.pojo.concurrent.Task$1.run(Task.java:60)
        at com.ups.ivr.ins.pojo.concurrent.Task.run(Task.java:127)
        at weblogic.work.j2ee.J2EEWorkManager$WorkWithListener.run(J2EEWorkManager.java:184)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
    Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
    Internal Exception: java.sql.SQLTransactionRollbackException: [FMWGEN][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 338) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
    Error Code: 1205
    Call: UPDATE TCALCNX SET CAL_CNX_B = ?, REC_STS_CD = ?, REC_UDT_TS = ? WHERE ((CAL_ID_NR = ?) AND (REC_UDT_TS = ?))
        bind => [[B@1c1f9699, 02, 2014-08-06 12:27:22.645, P4F21420140806182553001248, 2014-08-06 12:27:21.287]
    Query: UpdateObjectQuery(CALL ID :P4F21420140806182553001248
    REC_UDT_TS :2014-08-06 12:27:22.645
    REC_STS_CD:02
    SRC_DT_CNTR:10
    VERSION_NUM :001
    REC_SEQ_NR:1)
        at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
        at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
        at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.updateObject(DatasourceCallQueryMechanism.java:749)
        at org.eclipse.persistence.internal.queries.StatementQueryMechanism.updateObject(StatementQueryMechanism.java:432)
        at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1042)
        at org.eclipse.persistence.queries.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:84)
        at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:287)
        at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
        at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:743)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1449)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:265)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:128)
        at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3799)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1415)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:636)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1505)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3143)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:346)
        at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157)
        at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
        at weblogic.transaction.internal.ServerSCInfo.doBeforeCompletion(ServerSCInfo.java:1259)
        at weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(ServerSCInfo.java:1234)
        at weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(ServerSCInfo.java:123)
        at weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain(ServerTransactionImpl.java:1355)
        at weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare(ServerTransactionImpl.java:2172)
        at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:300)
        at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:267)
        at weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:307)
        at weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:301)
        at com.ups.ivr.ins.ejb.CallContentSession.Update(CallContentSession.java:276)
        at com.ups.ivr.ins.ejb.CallContentSession_95sf62_CallContentSessionLocalImpl.__WL_invoke(Unknown Source)
        at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:31)
        at com.ups.ivr.ins.ejb.CallContentSession_95sf62_CallContentSessionLocalImpl.Update(Unknown Source)
        at com.ups.ivr.ins.ejb.CallManager.saveCall(CallManager.java:130)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.ups.ivr.ins.pojo.concurrent.Task$1.run(Task.java:60)
        at com.ups.ivr.ins.pojo.concurrent.Task.run(Task.java:126)
        ... 3 more
    Caused by: java.sql.SQLTransactionRollbackException: [FMWGEN][SQLServer JDBC Driver][SQLServer]Transaction (Process ID 338) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
        at weblogic.jdbc.sqlserverbase.ddb_.b(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddb_.a(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddb9.b(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddb9.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.v(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddq.a(Unknown Source)
        at weblogic.jdbc.sqlserver.tds.ddr.a(Unknown Source)
        at weblogic.jdbc.sqlserver.ddj.m(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddel.e(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddel.a(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddde.a(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddel.v(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddel.x(Unknown Source)
        at weblogic.jdbc.sqlserverbase.ddde.executeUpdate(Unknown Source)
        at weblogic.jdbc.wrapper.PreparedStatement.executeUpdate(PreparedStatement.java:167)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
        ... 54 more
    

2 个答案:

答案 0 :(得分:2)

我不确定这与乐观锁定有什么关系(可能没有)。您应该减少在事务中正在执行的操作,以便他们获得的任何锁定都会保留较短的时间段,例如在绝对需要时仅调用flush。 Flush导致向DB发出语句,这些语句将比可能需要的更早获得锁,并且将一直保持到事务完全提交,从而使事务更容易发生冲突。

除了在修改相应实体时将更改的字段值添加到where子句之外,EclipseLink中的乐观锁定没有什么特别之处。这不会影响语句的顺序。可能是您的应用程序对乐观锁异常的处理导致延迟或额外的并发负载,如果它在有争议的行上反复重试相同的操作。

答案 1 :(得分:1)

Optimistic Locking是一种策略,您可以在其中读取记录,记下版本号(执行此操作的其他方法涉及日期,时间戳或校验和/哈希)并在写入之前检查版本是否未更改记录回来了。当你写回记录时,你过滤版本的更新,以确保它是原子的。

当使用乐观锁定时,我们仍然遇到锁定重新排序不能解决的死锁情况:

  • Tx1和Tx2事务在两个节点N1和N2上并行执行并写入密钥{a,b}

  • consistentHash(a)= {N3} and consistentHash(b)= {N4}

  • 有一些正确的时间,在准备期间,这两个交易可能会陷入僵局:

    • 在“a”@ N3
    • 上获得Tx1锁定
    • 在“b”@ N4
    • 上获得Tx2锁定
    • Tx1无法继续获取锁定“b”@ N4,该锁定由Tx2获取
    • Tx2无法锁定“a”@ N3,因为该锁被Tx1持有
    • Tx1和Tx2正在等待彼此⇒死锁

快速解决方案是将乐观锁定更改为悲观锁定以处理情况,否则我建议您link