Image
Top
Navigation

トランザクションを利用する

はじめに

OrientDBはNoSQLデータベースながらもトランザクションが利用可能です。

ただし、幾つか使用できない状況というのももちろん存在しますので、そういった情報を整理していきます。

OrientDBではローカル接続ではトランザクションが利用可能ですが、ローカル接続は排他接続のため現実的には利用するのはリモート接続となるかと思います。

ただし、リモート接続で利用する場合はバイナリプロトコルでの通信するAPIでのみトランザクショが利用可能です。

またOrientDBはDocumentデータベースとGraphデータベースが利用可能ですが、基本的にどちらもトランザクションが利用できますがそれぞれのJAVAのAPI上では使い方は若干異なります。

まずはどんなもんかためしてみいきましょう.

基本的な使い方

RollbackとCommitを試す

 Dcoument Database

まずは、単純にDocumentデータベースにてロールバック可能か確認します。
まずはコンソールからSQLにてrid = #22:22の内容を確認します。

orientdb {DocumentTest}> select from postoffice7 where @rid = #22:22
----+------+---------+----------+-----+-----+--------
#   |@RID  |name     |address   |lon  |lat  |id
----+------+---------+----------+-----+-----+--------
0   |#22:22|tran-sql0|テスト    |-10.0|-10.0|99999992
----+------+---------+----------+-----+-----+--------

1 item(s) found. Query executed in 0.002 sec(s).

こちらのlatフィールドをTransaction内で適当な値に更新したのちにRollbackしてみます。

package transaction;

import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.record.impl.ODocument;

public class RollbackTest_Document {

    public static void main(String[] args) {

        // リモートでデータベースへ接続します。
        ODatabaseDocumentTx database = new ODatabaseDocumentTx("remote:172.16.251.205/DocumentTest");
        database.open("root", "root");

        try {

            //トランザクショ開始
            database.begin();
            // デフォルトはTXTYPE.OPTIMISTIC. そのため下記の指定と同意
            // db.begin(TXTYPE.OPTIMISTIC);

            // RID #22:22のデータを取得
            OIdentifiable rec = database.load(new ORecordId("#22:22"));
            ODocument doc_ = rec.getRecord();

            // ドキュメントに含まれる全てのフィールドを表示する
            for (String fieldName : doc_.fieldNames()) {
                System.out.println(fieldName + " : " + doc_.field(fieldName));
            }

            // latフィールドを更新する。
            doc_.field("lat", 2.4);
            doc_.save();

            // ロールバックする
            database.rollback();

            // フィールドを再表示
            System.out.println("<フィールドを再表示>");
            for (String fieldName : doc_.fieldNames()) {
                System.out.println(fieldName + " : " + doc_.field(fieldName));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            database.close();
        }

    }
}
 
<実行結果>
name : tran-sql0
address : テスト
lon : -10.0
lat : -10.0
id : 99999992
<フィールドを再表示>
name : tran-sql0
address : テスト
lon : -10.0
lat : -10.0
id : 99999992

ちゃんとロールバックしているのが確認できます。
次に37行目のちょっと冗長ですが上のソースにてCommitするようにしてみましょう


            // latフィールドを更新する。
            doc_.field("lat", 2.4);
            doc_.save();

            // ロールバックする
            database.commit();
 
<実行結果>
name : tran-sql0
address : テスト
lon : -10.0
lat : -10.0
id : 9999999
<フィールドを再表示>
name : tran-sql0
address : テスト
lon : -10.0
lat : 2.4
id : 99999992

commit することによりこれで正しく反映されました。

 Graph Database

次にGraphデータベースでもためしてみます。
基本的な挙動は一緒ですが、データベース自体の扱い方(トランザクションに限らずですが)がDocumentデータベースとは若干ことなります。

まず、Documentデータベースの場合は、データベースへ接続後に beginメソッドでトランザクションを明示的に開始していますが、Graph データベースでは、接続の段階から、トランザクションを利用する場合はgetTx()、利用しない場合は、getNoTx()と呼び分ける必要が有ります。

commitとrollbackに関しては、Document データベースと同様の使い方ですね。
それではサンプルを見て行きましょう。
流れはDocumentデータベースのサンプルと同様ですが、今回は新規にデータを登録し、それをrollback、Commitを試すという非常に簡単なサンプルです。
まずは、コミットしてみましょう。


package transaction;

import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientBaseGraph;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;

public class GraphTransaction_lock4wp {

    /**
     * @param args
     */
    public static void main(String[] args) {

        // リモートでデータベースへ接続します。
        OrientGraphFactory factory = new OrientGraphFactory("remote:172.16.251.205/DocumentTest", "root", "root");
        // トランザクションを利用する場合はgetTx() 利用しない場合はgetNoTx()
        OrientBaseGraph graph = factory.getTx();

        try {

            Vertex node = graph.addVertex(null);
            node.setProperty("name", "テスト太郎");
            node.setProperty("test", 2);
            // コミットします
            graph.commit();

            System.out.println("コミット後に全ノードを取得");
            for (Vertex vertics : graph.getVertices()) {
                System.out.println(vertics.getId());
                for (String key : vertics.getPropertyKeys()) {
                    System.out.println(key + " " + vertics.getProperty(key));
                }
            }


        } catch (Exception e) {
            System.err.println(e);

            graph.rollback();
        } finally {
            graph.shutdown();

        }

    }
}
 
<実行結果>
コミット後に全ノードを取得
#9:8
test 2
name テスト太郎

上記のサンプルを今度はロールバックしてみます。


            Vertex node = graph.addVertex(null);
            node.setProperty("name", "テスト花子");
            node.setProperty("test", 3);
            // ロールバック後に全ノードを取得
            graph.rollback();
 
<実行結果>
コミット後に全ノードを取得
#9:8
test 2
name テスト太郎

追加したテスト花子はロールバックされているため表示されません。
こちらも問題なくロールバックされていることが確認できました。