0

2 つの Spring Batch ジョブがあります。最初のジョブ (ジョブ A) は、CRM システムから (Web サービスを介して) データを読み取り、それを Oracle データベース テーブルに書き込みます。2 つ目 (ジョブ B) - 正反対 - 同じ Oracle データベース テーブルからデータを読み取り、それを (Web サービス経由で) CRM に送信します。HibernateTemplate を使用してデータベース操作を行います。Oracle データベースに保存および更新するためのメソッドは、@Transactional(propagation = Propagation.REQUIRES_NEW) でマークされます。これらのバッチ ジョブは同時に動作します。ある時点で、2 つのジョブが互いにブロックします。 - Oracle データベースからレコードを読み取り中にジョブ A がブロックされ、データを読み取って CRM に送信する必要があるジョブがフリーズし、手動で停止するしかありません。-ジョブ 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: リソースの待機中にデッドロックが検出されました

特にSpringと一緒に動作する場合、Hibernateに慣れていません。私の理解では、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 に答える