Titan线程隔离的验证

Titan是一个分布式图数据库,具体可参考官方文档中的介绍。

本文旨在验证Titan多线程事务隔离的实现。具体地说,Titan Instance会为每个线程开启一个transaction,使得各个线程之间的操作是独立的,这就使得多线程应用的开发特别简单,各种线程只需共用一个Titan Instance即可。这是官方文档的说明:http://s3.thinkaurelius.com/docs/titan/0.5.4/tx.html#_transaction_handling

下面做一个简单的验证:
用两个线程来操作一个titan instance(即一个TitanGraph对象),其中一个线程不执行commit操作,看另一个线程的commit操作是否会提交所有对titan instance的修改。

package test;

import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.thinkaurelius.titan.core.TitanVertex;
import com.tinkerpop.blueprints.Vertex;

public class ThreadIsolatedTest {

    public static void main(String[] args) throws InterruptedException {
        final TitanGraph g = TitanFactory.open("inmemory"); // 为测试方便,使用inmemory模式

        Thread workerToCommit = new Thread(new Runnable() {
            @Override
            public void run() {
                String threadName = Thread.currentThread().getName();
                TitanVertex v = g.addVertex();
                System.out.println(threadName + " add vertex " + v.getId());
                try {
                    System.out.println(threadName + " is going to sleep 0.5s");
                    Thread.sleep(500);    // 等待另一个线程的操作完成
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                g.commit();
                System.out.println(threadName + " committed");
            }
        });
        Thread workerNotCommit = new Thread(new Runnable() {
            @Override
            public void run() {
                String threadName = Thread.currentThread().getName();
                TitanVertex v = g.addVertex();
                System.out.println(threadName + " add vertex " + v.getId());
                try {
                    System.out.println(threadName + " is going to sleep 1s");
                    Thread.sleep(1000);    // 等待另一个线程的commit发生,看是否会提交本线程的操作
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(threadName + " finished");
            }
        });

        workerNotCommit.start();   // 让不commit的线程先运行
        workerToCommit.start();
        workerNotCommit.join();
        workerToCommit.join();

        System.out.println("---------------- after committed --------------------");
        Iterable<Vertex> vs = g.query().vertices();
        System.out.println("committed vertex id:");
        for (Vertex v : vs) {
            System.out.println(v.getId());
        }
        g.shutdown();
    }
}

程度的输出结果如下:

Thread-2 add vertex 256
Thread-2 is going to sleep 0.5s
Thread-3 add vertex 512
Thread-3 is going to sleep 1s
Thread-2 committed
Thread-3 finished
---------------- after committed --------------------
committed vertex id:
256

首先 Thread-2 添加了一个 id 为 256 的点,然后先不 commit,而是 sleep 0.5秒,等待另一个线程的操作。
于是 Thread-3 添加了一个 id 为 512 的点,然后不 commit,而是 sleep 1秒,确保在本线程退出前,Thread-2 已经执行了 commit 操作。
然后 Thread-2 commit,之后 Thread-3 退出。

最后检查一下图中有哪些点,发现只有 Thread-2 提交的 256.

这足以证明,每个线程对 Titan Instance 的操作都是相互隔离的。Titan Instance 对操作它的线程透明地实现了事务隔离,具体的实现方式可参见下一篇文章。另外,如果不想要线程隔离,而是希望各个线程都在一个事务里,可以用 TitanGraph 的 newTransaction 函数获得一个事务,然后各个线程共用一个 Transaction 对象来实现,具体可参见文档 http://s3.thinkaurelius.com/docs/titan/0.5.4/tx.html#multi-thread-tx

猜你喜欢

转载自blog.csdn.net/huang_quanlong/article/details/50311101
今日推荐