Spring批处理作业同时访问数据库锁

时间:2013-06-18 11:28:25

标签: spring spring-batch locks

我有两个Spring Batch作业:第一个(作业A)从CRM系统(通过Web服务)读取数据并将其写入Oracle数据库表;第二个(作业B) - vise verse - 从同一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>

1 个答案:

答案 0 :(得分:0)

好的,首先你应该能够在oracle中找到这个死锁的跟踪日志。你可能会看到导致死锁的原因。

请参阅this thread

在您尝试处理事务级别的任何设置中,死锁都可能发生!您可能需要检查批处理的逻辑以及并行运行它们可能会导致更多武器的事实。

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

祝你好运