Upgrade to Pro — share decks privately, control downloads, hide ads and more …

6. ScalarDB Cluster Development - Exception han...

6. ScalarDB Cluster Development - Exception handling

本資料は、ScalarDBを用いたアプリケーション開発における「Exception(例外)処理」について解説したトレーニング資料です。

ScalarDBはオプティミスティックコンカレンシーコントロール(OCC)を採用しており、データ更新時の競合などによって様々な例外が発生する可能性があります。そのため、アプリケーション側で適切にトランザクションのロールバックやリトライを行う必要があります。

本スライドでは、ScalarDBで発生する例外を種類ごとに分類し、それぞれの対応方針と実装例を紹介しています。

【主な内容】
・ScalarDBにおける例外の階層構造と概要
・例外の種類ごとに必要な処理(Rollback / Retry)の違い
 - Rollbackが不要と思われる例外 (UnknownTransactionStatusException)
 - Rollbackが必要、Retryは不要と思われる例外 (IllegalArgumentException)
 - Rollbackが必要、Retryも必要と思われる例外 (TransactionException, CrudException, CommitConflictException など)
・各例外の具体的な発生例とキャッチ時のコード例

記載の内容を実際にお試しいただく際や、より詳細な仕様については、以下の公式ドキュメントと併せてご参照ください。
https://scalardb.scalar-labs.com/docs/latest/api-guide/#how-to-handle-exceptions

Avatar for Scalar, Inc.

Scalar, Inc. PRO

May 18, 2026

More Decks by Scalar, Inc.

Other Decks in Technology

Transcript

  1. 3 変更履歴 Version Date Name Supported products and versions Description

    1.0 Yuji Ochiai ScalarDB Cluster 3.15.1 First draft
  2. Exception java.lang.Exception +- RuntimeException | IllegalArgumentException +- TransactionException com.scalar.db.exception.transaction.TransactionException +-

    CrudException | +- CrudConflictException | +- UnsatisfiedConditionException +- CommitException | +- CommitConflictException +- TransactionNotFoundException +- UnknownTransactionStatusException ScalarDBはオプティミスティックコンカレンシーコントロール (OCC)を採⽤ 更新に対する競合が発⽣した場合には例外が発⽣ アプリケーション側で再試⾏を⾏う等の考慮が必要 Exception handling 5 ScalarDBにおける例外 https://scalardb.scalar-labs.com/docs/latest/api-guide/#how-to-handle-exceptions
  3. Exception処理の概要 https://scalardb.scalar-labs.com/docs/latest/api-guide/#how-to-handle-exceptions public class Sample { public static void main(String[]

    args) throws Exception { TransactionFactory factory = TransactionFactory.create("<CONFIGURATION_FILE DistributedTransactionManager transactionManager = factory.getTransactionMa int retryCount = 0; TransactionException lastException = null; while (true) { if (retryCount++ > 0) { // リトライ制御例 if (retryCount >= 3) { throw lastException; } TimeUnit.MILLISECONDS.sleep(100); } DistributedTransaction transaction = null; try { transaction = transactionManager.begin(); // Begin a transaction. // Execute CRUD operations in the transaction. transaction.commit(); // Commit the transaction. } catch (<前記Exception> e) { ... lastException = e; ... } } } } Exceptionの種類によって必要な処理に違い Rollbackが不要と思われる例外 UnknownTransactionStatusException Rollbackが必要、Retryは不要と思われる例外 IllegalArgumentException Rollbackが必要、Retryも必要と思われる例外 その他
  4. Rollbackが不要と思われる例外 UnknownTransactionStatusException catch (UnknownTransactionStatusException e) { // If you catch

    `UnknownTransactionStatusException` when committing the transaction, // it indicates that the status of the transaction, whether it was successful or not, is unknown. // In such a case, you need to check if the transaction is committed successfully or not and // retry the transaction if it failed. How to identify a transaction status is delegated to users. throw e; } トランザクションのステータス (成功したかどうか) が不明であることを⽰す、特殊な例外 トランザクションが正常にコミットされたかどうかを個別に確認が必要 失敗していた場合にはトランザクションを別途再試⾏
  5. Rollbackが必要、Retryは不要と思われる例外 IllegalArgumentException catch (IllegalArgumentException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } throw e; } 指定したパラメータなどがテーブル定義に合っていない場合 プログラムやデータに問題がある場合 発⽣例:  Partition Key とClustering Keyが設定されたテーブルに対して、Clustering Keyを指定せずに Update操作
  6. Rollbackが必要、Retryも必要と思われる例外 TransactionException catch (TransactionException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } lastException = e; // リトライ処理へ } ⼀時的または持続的障害が原因でトランザクションを開始できなかった場合 ⼀時的障害の場合はトランザクションを再試⾏可能 持続的障害の場合はトランザクションを開始できない可能性 発⽣例:  scalar.db.cluster.grpc.max_inbound_message_size等の値を超えるデータのやり取りがあった場合 誤ったScalarDB Clusterのアドレスを指定して、トランザクションの実⾏を試みた場合
  7. Rollbackが必要、Retryも必要と思われる例外 CrudException catch (TransactionException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } lastException = e; // リトライ処理へ } ⼀時的または持続的障害が原因でトランザクションを開始できなかった場合 ⼀時的障害の場合はトランザクションを再試⾏可能 持続的障害の場合はトランザクションを開始できない可能性 発⽣例:  書き込み権限のないユーザで、Updateトランザクションを実⾏
  8. Rollbackが必要、Retryも必要と思われる例外 CrudConflictException catch (CrudConflictException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } lastException = e; // リトライ処理へ } ⼀時的な障害 (競合エラーなど) が原因でトランザクション CRUD 操作が失敗 トランザクションを再試⾏可能 発⽣例:  ScalarDB Cluster環境において、存在しないトランザクションIDを利⽤してresumeをした場合
  9. Rollbackが必要、Retryも必要と思われる例外 UnsatisfiedConditionException catch (UnsatisfiedConditionException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } // アプリケーションの要件に従って処理を決定 } UnsatisfiedConditionException はミューテーション操作の条件が満たされていない場合 この例外は、アプリケーションの要件に従って処理を決定 https://scalardb.scalar-labs.com/docs/latest/api-guide#put-delete-and-update-with-a-condition 発⽣例:  MutationCondition updateIfExistsCondition = ConditionBuilder.updateIfExists()で設定した Conditionを付与したUpdate処理で、対象レコードが存在しない場合
  10. Rollbackが必要、Retryも必要と思われる例外 CommitException catch (CommitException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } lastException = e; // リトライ処理へ } ⼀時的または持続的障害が原因でトランザクションを開始できなかった場合 ⼀時的障害の場合はトランザクションを再試⾏可能 持続的障害の場合はトランザクションを開始できない可能性 発⽣例:  Envoyとは接続できるが、ScalarDB Clusterとは接続出来ない場合
  11. Rollbackが必要、Retryも必要と思われる例外 CommitConflictException catch (CommitConflictException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } lastException = e; // リトライ処理へ } ⼀時的な障害 (競合エラーなど) が原因でトランザクションのコミットが失敗場合に発⽣ トランザクションを最初から再試⾏可能 発⽣例:  Update処理において、トランザクションAが対象レコードの読み込みが完了した後、更新完了 (Commit完了)までに、トランザクションBが同じ対象レコードの更新を完了
  12. Rollbackが必要、Retryも必要と思われる例外 TransactionNotFoundException catch (TransactionNotFoundException e) { if (transaction != null)

    { try { transaction.rollback(); } catch (RollbackException ex) { ex.printStackTrace(); } } lastException = e; // リトライ処理へ } ⼀時的な障害 (競合エラーなど) が原因でトランザクションのコミットが失敗場合に発⽣ トランザクションを最初から再試⾏可能(resumeで失敗した場合には、beginで開始等) 発⽣例:  ScalarDB Core環境において、存在しないトランザクションIDを利⽤してresumeをした場合