我对期限交易有点困惑。 假设在事务A中,我们有两个命令C1和C2,在事务B中也是如此。 现在两个交易同时到来 这些观察结果是否正确?
事务A C1和C2的所有命令将首先完成(假设A先输入),然后只执行事务B的命令。
可以执行事务A或B的任何命令,但保证如果任何事务的任何命令失败,那么该事务将被回滚。
如果第二种情况为真,则默认情况下在事务中,它在完成之前不会锁定任何资源
如果第一种情况属实,那么默认情况下,事务会暂停对资源的锁定,直到完成为止。
谢谢
Amit Aggarwal
答案 0 :(得分:8)
我们需要谈谈ACID中的“I”(Neo4j符合ACID),它代表“隔离”。隔离级别告诉您,并发运行事务的彼此数据量有多少。
Neo4j中的默认隔离级别是“read committed”。这意味着在B提交之前,A不会看到B写入的数据。这是通过自动锁定实现的,其工作方式如下:
Neo4j在读取它们时会读取锁定节点和关系(您可以获得许多读取锁定),并在修改它们时写入锁定节点和关系。存在写锁定时无法获得读锁定,并且当存在另一个写锁定时无法获得写锁定。事务提交时会释放锁。
但是,在这种隔离级别可能会发生一些异常,其中一种称为“丢失更新”。
为了说明,让c为你的计数器值(我理解原子计数器是你最终的后者)。两个事务都将计数器递增1。
c=0
Tx1 reads c=0 (read locks c)
Tx2 reads c=0 (read locks c)
Tx1 writes c=1 (write locks c)
Tx1 commits (unlocks c)
Tx2 writes c=1 (because it thinks c is still 0, write locks c)
Tx2 commits (unlocks c)
Tx1的更新已丢失。
为了防止这种情况,您需要在读取当前值之前,通过事先明确地修改要修改的对象,将隔离级别更改为“可重复读取”。这样,任何其他并发运行的事务都无法修改它们。
c=0
Tx1 write locks c
Tx1 reads c=0
Tx2 tries to write lock c, has to wait
Tx1 writes c=1
Tx1 commits (unlocks c)
Tx2 write locks c (because it now can)
Tx2 reads c=1
Tx2 writes c=2
Tx2 commits (unlocks c)
希望能让事情更清晰。