0

我有两个 Spring Batch 作业:第一个(作业 A)从 CRM 系统(通过 Web 服务)读取数据并将其写入 Oracle 数据库表;第二个(作业 B) - 虎钳 - 从同一个 Oracle 数据库表中读取数据并将其发送到 CRM(通过 Web 服务)。我使用 HibernateTemplate 进行数据库操作。保存和更新到 Oracle 数据库的方法用 @Transactional(propagation = Propagation.REQUIRES_NEW) 标记。这些批处理作业同时工作。在某些时候,这两个作业相互阻塞: - 作业 A 在从 Oracle 数据库块中读取记录时,必须读取数据并将数据发送到 CRM 的作业冻结,我唯一能做的就是手动停止它。-job B 也冻结,然后抛出异常:

Caused by: org.hibernate.exception.LockAcquisitionException: could not execute update query
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:87)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:84)
    at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:396)
    at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:259)
    at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1141)
    at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:94)
    at org.springframework.orm.hibernate3.HibernateTemplate$39.doInHibernate(HibernateTemplate.java:1150)
    at org.springframework.orm.hibernate3.HibernateTemplate$39.doInHibernate(HibernateTemplate.java:1)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
    ... 60 more

原因:java.sql.SQLException: ORA-00060: 在等待资源时检测到死锁

我不熟悉 Hibernate,尤其是当它与 Spring 一起工作时。我的理解是 Hibernate 管理事务,但显然我错了。你能告诉我这些锁的原因在哪里吗?我的休眠设置是:

<property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            <prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.generate_statistics">true</prop>
            <prop key="hibernate.default_batch_fetch_size">0</prop>
            <prop key="hibernate.cache.use_structured_entries">true</prop>
            <prop key="hibernate.cache.use_query_cache">true</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.jdbc.batch_size">0</prop>
            <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
            <prop key="hibernate.connection.useUnicode">true</prop>
            <prop key="hibernate.connection.characterEncoding">UTF8</prop>
            <prop key="hibernate.mapping.precedence">class</prop>
            <prop key="hibernate.transaction.flush_before_completion">true</prop>
            <prop key="hibernate.connection.release_mode">auto</prop>
        </props>
    </property>
4

1 回答 1

0

好的,首先您应该能够在 oracle 中找到此死锁的跟踪日志。您可能会准确地看到导致死锁的原因。

看到这个线程

无论您在事务级别上尝试什么设置,死锁都会发生并且将会发生!您可能必须检查批处理的逻辑以及并行运行它们可能会导致更多的手臂然后好的事实。

在您的情况下,作业 A 和作业 B 可能会在 Oracle 数据库中锁定相同的记录。

祝你好运

于 2013-06-19T14:43:12.470 回答