2015-05-07 44 views
2

首先我将解释为什么我想手动设置写锁。我在基于Spring Data Neo4j的Web服务应用程序中使用Neo4j数据库。事务由Spring管理,我只使用@Transactional注释。但是,我遇到了导致数据库不一致的特定用例的问题。我有是事务性的方法,其目的是使这样的节点/关系数据库:如何在Spring管理事务中手动管理Neo4j锁

(对:人) - [:用途] - >(S:SIM_Card {电话号码: “XXX”})

它的算法如下:

如果没有与特定的电话号码(唯一的)一个SIM_Card

-check已经在数据库中(通过@Query暗号查询),

- 如果是得到这个节点,如果没有创建它,

- 检查是否有任何人连接到此SIM_具有使用关系的卡片(密码查询),

- 如果没有这样的人员创建并附加到SIM_Card。

不幸的是,当有很多请求时,它发生在我连接到多个Person的数据库SIM_Cards中。我假设该方法由两个并发线程执行。两者都读取数据库并使用相同的电话号码搜索SIM_Card,并且都获得数据库中没有此类SIM_Card的信息,因此他们创建它们,然后将两个单独的Person附加到它们。 PhoneNuber对于SIM_Card来说是唯一的,所以最终只有一个SIM_Card,但是两个人仍然存在,这不是预期的情况。 要解决这个问题,我想在单独的事务中创建SIM_Card,然后创建Person并在另一个事务中附加到此SIM_Card。在创建人员之前,我将检查是否没有人员已经连接。但是,在此之前,我想在SIM_Card上手动设置写入锁,并且假设其他交易将无法在此期间检查是否有/或没有任何人连接到此SIM_Card。它将不得不等待锁被释放,然后它会看到这个SIM_Card已经连接了Person,并且不会创建另一个。

为了实现这一点,我必须设法在@Transactional注释方法中设置Neo4j锁,并且我不知道该怎么做。我将衷心感谢您的帮助。

+0

你有没有发现这种情况下的解决方案?目前我碰到同样的问题,不知道如何获得写锁定,以便正确更新我的计数器。 – alexanoid

回答

0

我认为你必须放弃@Transactional在这种情况下,电线GraphDatabaseService实例到你的仓库(或服务),并启动交易并手动获取写入锁定(http://neo4j.com/docs/stable/javadocs/org/neo4j/graphdb/Transaction.html#acquireWriteLock(org.neo4j.graphdb.PropertyContainer)

+0

我的第一个想法是获取当前事务并使用它来获取锁。但是,我找不到通过@Transactional开始访问正在进行的事务的方式。因此,我放了这样的事情:\t事务t = graphDatabaseService.beginTx();来获得任何事务,但是,我不太确定会发生什么当我把这里面的交易方法。在日志中,我甚至没有在DEBUG级别上看到任何东西。当我把它们放在新交易或甚至锁定时什么都没有。没有日志,没有错误,我不知道它是否有效,因为它很难检查。 – Cob

+0

@Cob你有没有找到这种情况下的解决方案?目前我遇到了同样的问题,不知道如何获得写锁定,以便正确更新我的计数器。 – alexanoid