2016-05-02 7 views
1

dbにアクセスする2つのスプリングBean(Bean AおよびB)があります。両方のBeanはPROPAGATION_REQUIRED_NEWにあり、分離レベルはORACLE dbに対してREAD COMMITEDです。2つの別々のスプリングBeanでPROPAGATION_REQUIRED_NEWを使用するとOracle db lockが発生する

同じ表で異なる基準で2回選択(Hibernate経由)します。 次に、テーブルの各行に対してBean Bが呼び出され、テーブルの更新が行われます。 Bean Aがデータベースに対して1つのコール(選択)を行う場合、奇妙なことにはうまくいっています。 私はdba.stackexchangeからのクエリをチェックしました。それはBean Aの2番目の "選択"がdbロックを持っているときだけです。

注:なぜBean BにPROPAGATION_REQUIREDまたはPROPAGATION_NESTEDを使用しないのですか? 私たちはPROPAGATION_REQUIREDを使用しません。行のいずれかが失敗し、PROPAGATIONがネストされている場合、すべてをロールバックしないので、使用しているjdbcドライバのバージョンはサポートしていません。

私の現在の回避策は、選択をseperatly処理するBeanを持つことです。メインBeanはトランザクションを実行せず、2つの他のBeanを呼び出すだけです。私は、単に "select * from X"を実行すると、テーブルをロックする原因がNONEにロックされ、READ_COMMITEDになってしまっているのが本当に奇妙なことがわかります。私はここに何かを逃していますか

最初のクエリ:

select 
    temptable0_.ID as ID1_43_, 
    temptable0_.IDSEND as IDS2_43_, 
    temptable0_.DATERECEI as DAT3_43_, 
    temptable0_.DATEPROC as DAT4_43_, 
    temptable0_.STATUT as STA5_43_, 
    temptable0_.ERROR_TYPE as ERR6_43_, 
    temptable0_.CODE as COD7_43_, 
    temptable0_.DESCRIPTION as DES8_43_, 
    temptable0_.NOTIF as NOT9_43_, 
    temptable0_.ACTION as ACT10_43_, 
    temptable0_.IDCLIENT as IDC11_43_, 
    temptable0_.PARAM as PAR12_43_ 
from 
    TABLE_TMP temptable0_ 
where 
    temptable0_.STATUT in (
     'NEW' 
    ) 

2番目のクエリ(同じトランザクション(BEAN A))

select 
    temptable0_.ID as ID1_43_, 
    temptable0_.IDSEND as IDS2_43_, 
    temptable0_.DATERECEI as DAT3_43_, 
    temptable0_.DATEPROC as DAT4_43_, 
    temptable0_.STATUT as STA5_43_, 
    temptable0_.ERROR_TYPE as ERR6_43_, 
    temptable0_.CODE as COD7_43_, 
    temptable0_.DESCRIPTION as DES8_43_, 
    temptable0_.NOTIF as NOT9_43_, 
    temptable0_.ACTION as ACT10_43_, 
    temptable0_.IDCLIENT as IDC11_43_, 
    temptable0_.PARAM as PAR12_43_ 
from 
    TABLE_TMP temptable0_ 
where 
    temptable0_.STATUT in (
     'ERROR' 
    ) 

そして(BEAN Bによって行われる)UPDATE文

update 
     TABLE_TMP 
    set 
     IDSEND=?, 
     DATERECEI=?, 
     DATEPROC=?, 
     STATUT=?, 
     ERROR_TYPE=?, 
     CODE=?, 
     DESCRIPTION=?, 
     NOTIF=?, 
     ACTION=?, 
     IDCLIENT=?, 
     PARAM=? 
    where 
     ID=? 

IDSENDがインクリメントされている場合は、DATEPROCが設定され、エラーまたは成功した場合はSTATUTおよびERROR_TYPEが設定されます。

+0

関連:http://stackoverflow.com/questions/8490852/spring-transactional-isolation-propagation – Chris

+3

jdbc仕様またはSpring抽象概念を信頼しないで、代わりにOracleが動作するかどうかを確認してください。 –

+1

Oracleはダーティ・リード(READ UNCOMMITED)をサポートしていません。 Plus:実際のSQL文を表示する必要があります。平文のSELECT文は、他のトランザクションをロックしません。また、他の文でロックされることもありません。 –

答えて

2

Oracleは、READ UNCOMMITEDをサポートしていません。あなたはREAD COMMITTEDでデフォルトモードを使用しています。

保留中のトランザクション変更があるレコードを他のセッションから選択しようとすると、更新がコミットされるまで待つ必要があります。

+0

読んでいるところREAD UNCOMMITTED分離レベルではダーティ・リードが可能ですが、Oracle Database doesn汚い読みを使うことも許さない。 READ UNCOMMITTED分離レベルの基本的な目標は、ノンブロッキング読み取りを可能にする標準ベースの定義を提供することです。出典:http://www.oracle.com/technetwork/issue-archive/2010/10-jan/o65asktom-082389.html – Chris

+0

READ COMMITTEDがデフォルトであり、READの代わりにREAD COMMITTEDを使用しているようです未定。私はそれがちょうど一連の更新作業の前に読み取り(選択)を行うが、更新が更新される前に2つのクエリを持つという1つのクエリがロックを生成するということはありません。 – Chris

関連する問題