1

この投稿は、JPA の永続性の問題に関するものです。使用される JPA プロバイダーは、weblogic 12c によって提供される Oracle Toplink であり、EclipseLink を使用して構築されます。

ユーザーは「n」回の対話/トランザクションを行い、アプリは各トランザクションを DB に書き込みます。負荷が高い場合、トランザクションの書き込み中にアプリで重複キーの例外が発生します。

最初のトランザクションは DB に正常に書き込まれますが、後続のトランザクションは重複キー例外で拒否されることがあります。

私が言ったように、アプリは共有キャッシュがデフォルトで有効になっているJPA 2.0を使用しています。これは共有キャッシュと関係があると思います。

これは、JPA 1.0 を使用する Weblogic 10 でも同じアプリが正常に動作し、共有キャッシュの概念がないためです。

ここで問題に戻ります。挿入トランザクションに参加する各エンティティは、オーバーライドされた hashcode/equals() を持つ埋め込まれた主キー クラスによって一意に識別されます (クラス定義については以下を参照してください)。

@EmbeddedId
private CallerEntityPK pk;

//@Column attributes    

}

@Embeddable
public class CallerEntityPK implements Serializable {

    @Column(name="SESSION_ID")
    private String sessionId;   //FIRST_USER_SESSION,SECOND_USER_SESSION

    @Column(name="TRANSACTION_NBR")
    private String transNo;     //01 , 02 etc... 

    //Getter setters

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if ( ! (o instanceof CallerEntity )) {
            return false;
        }
        CallerEntity other = (CallerEntity ) o;
        return this.sessionId.equals(other.sessionId)
            && this.transNo.equals(other.transNo;);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int hash = 17;
        hash = hash * prime + this.sessionId.hashCode();
        hash = hash * prime + this.transNo.hashCode();
        return hash;
    }
}

主キーは、sessionid(FIRST_USER_SESSION) とトランザクション番号 (最初の挿入の場合は 01、2 番目の挿入の場合は 02 ....) の組み合わせです。例: FIRST_USER_SESSION と 01

1 番目のトランザクション pk: FIRST_USER_SESSION01 2 番目のトランザクション pk: FIRST_USER_SESSION02

  1. 最初の挿入トランザクション (pk FIRST_USER_SESSION 01 のエンティティ) を書き込む前に、L2 キャッシュでチェックされ、キャッシュにないため、DB に正常に永続化されました。

  2. 最初のトランザクションを書き込んだ後、L2 キャッシュで更新されます (FIRST_USER_SESSION 01 キーを持つエンティティがキャッシュされます)。

  3. 2 番目の挿入トランザクション (キー FIRST_USER_SESSION 02 を持つエンティティ) の場合、永続化する前に L2 キャッシュがチェックされ、2 番目のトランザクションのエンティティは L2 キャッシュに既に存在するエンティティと同一であると考えられます。pk は異なりますが (FIRST_USER_SESSION02)、フレームワークはそれを重複オブジェクトとして識別していると思います (equals() と hashcode() のオーバーライドに基づく)。

その結果、挿入のために同じ重複オブジェクトが試行され、重複キー例外がスローされます。

質問 1) 私の理解は正しいですか? これを尋ねている理由は、すべてのエンティティが一意のキーを持っており、これは大量の場合にのみ発生するためです。他のトランザクション(エンティティ)が同じハッシュコードを返し、オブジェクトを同一にしている可能性があります。

質問 2) この場合、エンティティが分離キャッシュを使用し、常に更新され、すぐに期限切れになるようにすることはできますか (以下のコードを参照)。
このエンティティのキ​​ャッシュを無効にしたいだけです。コメントをお知らせください

@Entity 
@Table(name="T_CALLER_TRANS") 
@Cache(isolation=CacheIsolationType.ISOLATED, expiry=0, alwaysRefresh=true)
public class CallerEntity implements Serializable {

}

質問 3) この変更を行った後、アプリケーションの負荷テストを行う必要があります。アプリに対するユーザーは、MQ および HTTP を介して対話します。MQ に十分なメッセージを送信する必要がある

4

0 に答える 0