sql >> データベース >  >> RDS >> Oracle

SpringデータJPAクエリで@lockタイムアウトを指定するにはどうすればよいですか?

    SpringData1.6以降の場合

    @Lock Spring Data JPAのバージョン1.6以降のCRUDメソッドでサポートされています(実際、マイルストーン 利用可能)。このチケット をご覧ください 詳細については。

    そのバージョンでは、次のことを宣言するだけです。

    interface WidgetRepository extends Repository<Widget, Long> {
    
      @Lock(LockModeType.PESSIMISTIC_WRITE)
      Widget findOne(Long id);
    }
    

    これにより、バッキングリポジトリプロキシのCRUD実装部分が、構成されたLockModeTypeをfind(…)に適用します。 EntityManagerを呼び出す 。

    一方、

    以前のバージョンのSpringData1.6の場合

    春のデータ悲観的な@Lock アノテーションは(ご指摘のとおり)クエリにのみ適用されます。トランザクション全体に影響を与える可能性があると私が知っている注釈はありません。 findByOnePessimisticを作成することができます findByOneを呼び出すメソッド 悲観的なロックを使用するか、findByOneを変更できます 常に悲観的なロックを取得します。

    独自のソリューションを実装したい場合は、おそらく可能です。内部では、@Lock アノテーションはLockModePopulatingMethodIntercceptorによって処理されます これは次のことを行います:

    TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
    

    ThreadLocal<LockMode>を持つ静的ロックマネージャーを作成できます。 メンバー変数を作成し、ThreadLocalで設定されたロックモードでbindResourceを呼び出したすべてのリポジトリのすべてのメソッドにアスペクトをラップします。これにより、スレッドごとにロックモードを設定できます。次に、独自の@MethodLockModeを作成できます。 メソッドを実行する前にスレッド固有のロックモードを設定し、メソッドの実行後にそれをクリアするアスペクトでメソッドをラップするアノテーション。

    リソースリンク:

    1. Spring Data JPAでエンティティを検索するときにLockModeType.PESSIMISTIC_WRITEを有効にするにはどうすればよいですか?
    2. カスタムを追加する方法SpringDataJPAの方法
    3. PostgresでのSpringDataPessimisticLockタイムアウト
    4. JPAクエリAPI

    ペシミスティックロックタイムアウトのさまざまな例

    ペシミスティックロックの設定

    エンティティオブジェクトは、lockメソッドによって明示的にロックできます:

    em.lock(employee, LockModeType.PESSIMISTIC_WRITE);
    

    最初の引数はエンティティオブジェクトです。 2番目の引数は要求されたロックモードです。

    TransactionRequiredException 明示的なロックにはアクティブなトランザクションが必要なため、ロックが呼び出されたときにアクティブなトランザクションがない場合にスローされます。

    LockTimeoutException 要求されたペシミスティックロックを付与できない場合にスローされます:

    • PESSIMISTIC_READ 別のユーザー(別のEntityManagerインスタンスによって表される)が現在PESSIMISTIC_WRITEを保持している場合、ロック要求は失敗します そのデータベースオブジェクトをロックします。
    • PESSIMISTIC_WRITE 別のユーザーが現在PESSIMISTIC_WRITEのいずれかを保持している場合、ロック要求は失敗します ロックまたはPESSIMISTIC_READ そのデータベースオブジェクトをロックします。

    クエリヒント(スコープ)の設定

    クエリヒントは、次のスコープ(グローバルからローカルまで)で設定できます:

    永続性ユニット全体の場合-persistence.xmlを使用 プロパティ:

    <properties>
       <property name="javax.persistence.query.timeout" value="3000"/>
    </properties>
    

    EntityManagerFactoryの場合-createEntityManagerFacotoryを使用 方法:

    Map<String,Object> properties = new HashMap();
    properties.put("javax.persistence.query.timeout", 4000);
    EntityManagerFactory emf =
      Persistence.createEntityManagerFactory("pu", properties);
    

    EntityManagerの場合-createEntityManagerを使用 方法:

    Map<String,Object> properties = new HashMap();
    properties.put("javax.persistence.query.timeout", 5000);
    EntityManager em = emf.createEntityManager(properties);
    

    またはsetPropertyメソッドを使用します:

    em.setProperty("javax.persistence.query.timeout", 6000);
    

    named queryの場合 定義-hintsを使用 要素:

    @NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
        hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})
    

    特定のクエリ実行の場合-setHintを使用 メソッド(クエリ実行前):

    query.setHint("javax.persistence.query.timeout", 8000);
    

    リソースリンク:

    1. JPAでのロック
    2. ペシミスティックロックタイムアウト


    1. postgresでフィールドのデータ型を選択します

    2. PLSQLを使用してApex表形式を更新

    3. mysqlの自動インクリメントはuserIDとして安全に使用できますか?

    4. データが存在しない場合でも、12か月すべての結果を表示するにはクエリを選択します