翻译整理:纪玉奇
 
几乎所有与JanusGraph的交互都是通过Transaction,JansuGraph的Transaction支持并发。使用Transaction时,不需要显式进行生命,graph.V()即会开启一个事务,graph.commit()则会提交一个事务。用户也可以使用graph.newTransaction()获取对事务的控制权。
另外,事务不一定是ACID,而是依赖于后端支持情况,如果是BerkleyDB则可以,但不被Cassandra和HBase支持。

Transaction Handling

对JanusGraph的每个操作都是在事务执行,无需显式声明,由第一次操作开启。
graph = JanusGraphFactory.open("berkeleyje:/tmp/janusgraph")
juno = graph.addVertex() //Automatically opens a new transaction
juno.property("name", "juno")
graph.tx().commit() //Commits transaction

graph = JanusGraphFactory.open("berkeleyje:/tmp/janusgraph")
juno = graph.addVertex() //Automatically opens a new transaction
juno.property("name", "juno")
graph.tx().commit() //Commits transaction
 
事务在commit()或数据库shutdown()时才结束。

Transaction Scope

vertices, edges和type都在transaction scope的范围中,在Tinpop的默认语法,transaction是自动创建的,一旦提交和关闭,元素则不可用。
对于vertex来说,JanusGraph将会自动创建一个vertices并交由一个新的transaction scope,用户就无需显式声明了。
graph = JanusGraphFactory.open("berkeleyje:/tmp/janusgraph")
juno = graph.addVertex() //Automatically opens a new transaction
graph.tx().commit() //Ends transaction
juno.property("name", "juno") //Vertex is automatically transitioned

graph = JanusGraphFactory.open("berkeleyje:/tmp/janusgraph")
juno = graph.addVertex() //Automatically opens a new transaction
graph.tx().commit() //Ends transaction
juno.property("name", "juno") //Vertex is automatically transitioned
对于Edge,不会自动创建新的transaction,而且无法在初始transaction之外访问,需要显式创建:

Transaction Failures

当提交事务时,由于各种原因,往往不会成功,如因为网络问题,IO问题等。实际上,对于大型系统,事务将会最终失败。
try {
if (g.V().has("name", name).iterator().hasNext())
throw new IllegalArgumentException("Username already taken: " + name)
user = graph.addVertex()
user.property("name", name)
graph.tx().commit()
} catch (Exception e) {
//Recover, retry, or return error message
println(e.getMessage())
}
如果事务执行失败,将会抛出JanusGraphException,失败原因有很多种,可以分为如下两类:
  • Potentially temporary failures
由于IO,网络原因导致的失败,重试可能成功,且由JanusGraph自动重试,在配置其重试次数。
  • Permanent failures
产生于完全的网络断开或锁。

Multi-Threaded Transactions

JanusGraph通过tinkerpop的transactions支持multi-threaded transaction,通过多线程可以充分利用多核CPU。要开启多线程事务,需要使用createThreadedTx()方法。
threadedGraph = graph.tx().createThreadedTx();
threads = new Thread[10];
for (int i=0; i<threads.length; i++) {
threads[i]=new Thread({
println("Do something with 'threadedGraph''");
});
threads[i].start();
}
for (int i=0; i<threads.length; i++) threads[i].join();
threadedGraph.tx().commit();
Concurrent Algorithms
当实现并发图算法时经常使用createThreadedTx()方法。

Nested Transactions 嵌套事务

当在一个事务中逻辑较长时,占有锁的时间也较长,很有可能发生竞争。如下面的情况:
v1 = graph.addVertex()
//Do many other things
v2 = graph.addVertex()
v2.property("uniqueName", "foo")
v1.addEdge("related", v2)
//Do many other things
graph.tx().commit() // This long-running tx might fail due to contention on its uniqueName lock
针对此种情况,可以采用在一个短的,嵌套的、线程无关的事务中创建一个顶点,如下示:
v1 = graph.addVertex()
//Do many other things
tx = graph.tx().createThreadedTx()
v2 = tx.addVertex()
v2.property("uniqueName", "foo")
tx.commit() // Any lock contention will be detected here
v1.addEdge("related", g.V(v2).next()) // Need to load v2 into outer transaction
//Do many other things
graph.tx().commit() // Can't fail due to uniqueName write lock contention involving v2

Common Transaction Handling Problems

事务不用手动启动,需要手动启动的只有multi-threaded transaction。
事务是由Tinkerpop的语句自动启动的,但是需要显式的关闭,这种操作很有必要,因为只有使用者知道事务的范围。完成一个事务需要执行g.commit()或g.rollback(),事务将试图从一开始就维护状态,而这很可能导致问题。
v = g.V(4).next() // Retrieve vertex, first action automatically starts transaction
g.V(v).bothE()
>> returns nothing, v has no edges
//thread is idle for a few seconds, another thread adds edges to v
g.V(v).bothE()
>> still returns nothing because the transactional state from the beginning is maintained
从上面的代码中可以看出,由于事务没有结束,对象的状态得意维持,另外线程的更改没有体现出来。这个问题通常出现在客户端-服务器模式部署的场景下,为了解决此问题,用户需要在执行完毕后手工调用commit()方法。
v = g.V(4).next() // Retrieve vertex, first action automatically starts transaction
g.V(v).bothE()
graph.tx().commit()
//thread is idle for a few seconds, another thread adds edges to v
g.V(v).bothE()
>> returns the newly added edge
graph.tx().commit()
在使用multi-threaded事务时,在事务范围内创建的所有的vertices和edges在事务外均不可见,在事务结束后访问这些元素将会导致错误。根据上面展示的,这些element需要在新事务中显示刷新,使用:
g.V(existingVertex)或者g.E(existingEdge)

Transaction Configruation

JanusGraph.buildTransaction()方法给了用户设置和启动multi-threaded transaction的能力,也可以通过JanusGraph.newTransaction()进行设置。
 
  • readOnly()
  • enableBatchLoading()
  • setTimestamp()
  • setVertexCacheSize(long)
  • checkExternalVertexExistence(boolean)
  • checkInternalVertexExistence(boolean)
  • consistencyChecks(boolean)

JanusGraph中的事务的更多相关文章

  1. Microsoft SQL Server中的事务与并发详解

    本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...

  2. Redis系列之key操作命令与Redis中的事务详解(六)

    序言 本篇主要目的有二: 1.展示所有数据类型中key的所有操作命令,以供大家学习,查阅,更深入的挖掘redis潜力. 2.掌握redis中的事务,让你的数据完整性一致性拥有更优的保障. redis命 ...

  3. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  4. 【转】SQL Server中的事务与锁

    SQL Server中的事务与锁   了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂 ...

  5. 存储过程中使用事务,sql server 事务,sql事务

    一.存储过程中使用事务的简单语法       在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server存储过程中使用事务也很简单,用一个例子来说明它的语法格式: 代码 ...

  6. 【MySQL】漫谈MySQL中的事务及其实现

    最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySQL,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...

  7. SQL Server中的事务日志管理(9/9):监控事务日志

    当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...

  8. Spring中的事务

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  9. SQL2005中的事务与锁定(八)- 转载

    ------------------------------------------------------------------------ -- Author : happyflystone - ...

随机推荐

  1. Z-Stack协议栈网络号与信道号的设置

    1.网络号设置 默认是:-DZDAPP_CONFIG_PAN_ID=0xFFFF 代表的是随机选择一个网络号,并加入此网络,可以将0xffff改成4位数字,如图所示. 2.信道号的设置 这个地方在网络 ...

  2. Problem G: 零起点学算法102——删除字符

    #include<stdio.h> #include<string.h> int main() { ],a; while(gets(ch)!=NULL) { scanf(&qu ...

  3. google的开源项目总结

    转自http://www.feng5166.com/blog/424.html google的开源项目值得我们一用的,这些项目很有意义,甚至可以直接用在我们自己的工作上!学习编程的的一个比较好的方式就 ...

  4. mac远程链接 windows

    https://bbs.feng.com/read-htm-tid-10516042.html 一.利用电脑系统自带的远程(喜欢懒人版的方法,或者小白用户,可以跳过这个方法看下一个) 1.打开mac, ...

  5. Dos网络查看命令

    net use //ip/ipc$ " " /user:" " 建立IPC空链接 net use //ip/ipc$ "密码" /user: ...

  6. python微信公众号开发学习记录

    网上有很多微信公众号的开发教程,但是都是好几年前的了,而且很多都是抄袭其他人的,内容几乎一模一样.真的无语了.只好自己总结一下开发的一些简单流程. 一先去注册个微信公众号,这个就不详细说了, 二登录后 ...

  7. python numpy学习记录

    numpy是一个python和矩阵相关的库,在机器学习中非常有用,记录下numpy的基本用法 numpy的数组类叫做ndarray也叫做数组,跟python标准库中的array.array不同,后者只 ...

  8. zend 环境

    js智能提示: 安装APTANA组件,最新3.0版本 安装地址:http://download.aptana.com/studio3/plugin/install Aptana 3 不能装 2 的 J ...

  9. 如何使用 awk 的 ‘next’ 命令

    导读 在 awk 系列文章中,我们来看一下next 命令 ,它告诉 awk 跳过你所提供的所有剩下的模式和表达式,直接处理下一个输入行.next 命令帮助你阻止运行命令执行过程中多余的步骤. 要明白它 ...

  10. ESLint:can not ESLint annotation...

    刚开始用webstorm开发VUE,提示这个东西: 安装一个npm库就可以了 命令行执行:npm install eslint -g