S-JIS[2023-10-07] 変更履歴

Tsubakuro KVSクライアント

TsurugiTsubakuro(Java通信ライブラリー)のKvsClientのメモ。


概要

Tsurugiサーバーの内部はKVS(Key Value Store)でデータを管理している。
TsurugiのSQL実行エンジンは、SQL文を「KVSアクセスする処理」に変換して実行する。
Tsubakuroでは(SQLを介さずに)KVSアクセスすることが出来る。
(元々は、JavaからKVSアクセスする機能は予定に入っておらず、C++でKVSアクセスする処理を書けるようになる予定だった)

KVSアクセスではput/get/remove/scanなど、テーブル単位での読み書きの機能しか無い。
SQLより単純だが、その分速いはず。

TsubakuroでKVSアクセスするにはKvsClientクラスを使用する。
ただし、Tsurugi 1.0.0-BETA1ではまだ正式公開されておらず、限定的な機能しか使用できない。
(なお、Tsurugiサーバーのバージョン付けとTsubakuro(クライアント)のバージョンは一致していない)

KvsClientはtsubakuro-kvsにあるので、biuld.gradleのdependenciesに追加する必要がある。

biuld.gradle:

dependencies {
    def tsubakuroVersion = '1.0.1'
    implementation "com.tsurugidb.tsubakuro:tsubakuro-session:${tsubakuroVersion}"
    implementation "com.tsurugidb.tsubakuro:tsubakuro-connector:${tsubakuroVersion}"
    implementation "com.tsurugidb.tsubakuro:tsubakuro-kvs:${tsubakuroVersion}"
}
SqlClientとKvsClientの違い
  SqlClient KvsClient
トランザクションの開始方法 SqlClientからTransactionを生成する。 KvsClientからTransactionHandleを生成する。
処理の実行方法 TransactionのメソッドでSQLを実行する。 KvsClientのメソッドでKVSアクセス処理を実行する。
その際にTransactionHandleを引数で渡す。

KvsClientを生成する例

KvsClientインスタンスはSessionをアタッチして生成する。

import com.tsurugidb.tsubakuro.kvs.KvsClient;
    try (var kvsClient = KvsClient.attach(session)) {
        〜
    }

KvsClientはクローズする必要があるが、クローズしてもアタッチされたSessionはクローズされない。


トランザクションを実行する例

import com.tsurugidb.tsubakuro.kvs.TransactionHandle;
import com.tsurugidb.tsubakuro.kvs.TransactionOption;
    try (var kvsClient = KvsClient.attach(session)) {

        // トランザクション開始
        TransactionOption option = TransactionOption.forShortTransaction().build();
        try (TransactionHandle transactionHandle = kvsClient.beginTransaction(option).await(3, TimeUnit.SECONDS)) {
            〜

            // コミット
            kvsClient.commit(transactionHandle).await(10, TimeUnit.SECONDS);
        }
    }

KvsClientのメソッド

メソッド 説明
attach SessionをアタッチしてKvsClientインスタンスを生成する。 try (var kvsClient = KvsClient.attach(session)) {
}
beginTransaction トランザクションを開始する。(TransactionHandleを生成する) try (FutureResponse<TransactionHandle> future = kvsClient.beginTransaction(transactionOption)) {
}
commit トランザクションをコミットする。 try (FutureResponse<Void> future = kvsClient.commit(transactionHandle)) {
}
try (FutureResponse<Void> future = kvsClient.commit(transactionHandle, commitType)) {
}
rollback トランザクションをロールバックする。 try (FutureResponse<Void> future = kvsClient.rollback(transactionHandle)) {
}
get キーを指定してテーブルから1行取得する。
getの例
try (FutureResponse<GetResult> future = kvsClient.get(transactionHandle, tableName, key)) {
}
put テーブルに1行書き込む。
putType省略時はOVERWRITEと同じ。
putの例
try (FutureResponse<PutResult> future = kvsClient.put(transactionHandle, tableName, record, putType)) {
}
remove キーを指定してテーブルから1行削除する。
removeType省略時はCOUNTINGと同じ。
removeの例
try (FutureResponse<RemoveResult> future = kvsClient.remove(transactionHandle, tableName, key, removeType)) {
}
scan テーブルから複数行取得する。
Tsurugi 1.0.0-BETA1では未実装。
 
batch 複数のKVS操作をまとめて実行する。
Tsurugi 1.0.0-BETA1では未実装。
 

getremoveメソッドにおける「キー」は、基本的にプライマリキー。
ただしインデックスが作られているテーブルでは、インデックスも指定できるようになるらしい?


putの例

KvsClientのputメソッドは、テーブルに1行書き込む。

import com.tsurugidb.tsubakuro.kvs.PutResult;
import com.tsurugidb.tsubakuro.kvs.PutType;
import com.tsurugidb.tsubakuro.kvs.RecordBuffer;
    var record = new RecordBuffer();
    record.add("pk", 1);       // int
    record.add("value", 456L); // bigint
    PutResult result = kvsClient.put(transactionHandle, "test", record, PutType.OVERWRITE).await(3, TimeUnit.SECONDS);

    System.out.printf("put.size=%d%n", result.size());

RecordBufferでテーブルの1行分のデータを設定する。(全カラムのデータが必須)
それをテーブル名と共にputメソッドに渡す。

putメソッドの引数PutTypeの意味は以下の通り。

PutType 説明 備考
OVERWRITE
(デフォルト)
テーブルにレコードが存在していたら更新し、無かったら追加する。 SQLのinsert or replace相当
IF_ABSENT テーブルにレコードが存在しない場合だけ追加する。(存在する場合は何もしない) SQLのinsert相当
IF_PRESENT テーブルにレコードが存在する場合に更新する。(存在しない場合は何もしない) SQLのupdate相当

putでは、SQLのinsert文と異なり、プライマリキーの一意制約違反が発生することは無い。


putメソッドの実行結果として、PutResultが返る。

PutResultにはsizeメソッドがあり、実際に書き込んだ件数が返る。


getの例

KvsClientのgetメソッドは、キーを指定してテーブルから1行取得する。

import com.tsurugidb.tsubakuro.kvs.GetResult;
import com.tsurugidb.tsubakuro.kvs.Record;
import com.tsurugidb.tsubakuro.kvs.RecordBuffer;
    var key = new RecordBuffer();
    key.add("pk", 1);
    GetResult result = kvsClient.get(transactionHandle, "test", key).await(3, TimeUnit.SECONDS);

    if (result.isSingle()) {
        Record record = result.asRecord();
        int pk = record.getInt("pk");
        Long value = record.isNull("value") ? null : record.getLong("value");
        System.out.printf("%d, %d%n", pk, value);
    } else {
        System.out.println("get nothing");
    }

RecordBufferでテーブルのキーのデータを設定する。(複合キーの場合、それら全てのデータが必須)
それをテーブル名と共にgetメソッドに渡す。


getメソッドの実行結果として、GetResultが返る。

指定したキーのデータがあったかどうかはGetResultのisSingleメソッドで判別できる。
trueの場合、GetResultのasRecordメソッドで1レコード分のデータが取得できる。


removeの例

KvsClientのremoveメソッドは、キーを指定してテーブルから1行削除する。

import com.tsurugidb.tsubakuro.kvs.RecordBuffer;
import com.tsurugidb.tsubakuro.kvs.RemoveResult;
import com.tsurugidb.tsubakuro.kvs.RemoveType;
    var key = new RecordBuffer();
    key.add("pk", 1);
    RemoveResult result = kvsClient.remove(transactionHandle, "test", key, RemoveType.COUNTING).await(3, TimeUnit.SECONDS);

    System.out.printf("remove.size=%d%n", result.size());

RecordBufferでテーブルのキーのデータを設定する。(複合キーの場合、それら全てのデータが必須)
それをテーブル名と共にremoveメソッドに渡す。

removeメソッドの引数RemoveTypeの意味は以下の通り。

RemoveType 説明
COUNTING
(デフォルト)
実際に削除した件数を返す。(RemoveResultのsizeメソッド)
INSTANT 削除件数を返さない。(RemoveResultのsizeメソッドは常に1を返す)
削除対象が存在したかどうかのチェックを行わない分、速いのだと思われる。

removeメソッドの実行結果として、RemoveResultが返る。

RemoveTypeがCOUNTINGの場合、RemoveResultのsizeメソッドで実際に削除した件数が分かる。(と言っても、キーを指定するので、削除件数は1か0のどちらかだろう)
RemoveTypeがINSTANTの場合は、RemoveResultのsizeメソッドは常に1を返す。


Tsubakuroへ戻る / Tsurugiへ戻る / 技術メモへ戻る
メールの送信先:ひしだま