【问题标题】:How to manually manage Neo4j locks in Spring managed transaction如何在 Spring 托管事务中手动管理 Neo4j 锁
【发布时间】:2015-05-07 18:47:10
【问题描述】:

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

(p:Person)-[:USES]->(s:SIM_Card{phoneNumber:"xxx"})

其算法如下:

-检查数据库中是否已经存在具有特定电话号码(唯一)的 SIM_Card(通过 @Query 进行密码查询),

-如果是则获取该节点,如果否则创建它,

-检查是否有任何人与使用关系(密码查询)连接到此 SIM_Card,

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

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

为了实现这一点,我必须以某种方式在 @Transactional 注释方法中设置 Neo4j 锁,但我不知道该怎么做。非常感谢您的帮助。

【问题讨论】:

标签: neo4j spring-data-neo4j


【解决方案1】:

我认为在这种情况下你必须放弃@Transactional,将GraphDatabaseService实例连接到你的存储库(或服务)中,并启动事务并手动获取写锁(http://neo4j.com/docs/stable/javadocs/org/neo4j/graphdb/Transaction.html#acquireWriteLock(org.neo4j.graphdb.PropertyContainer)

【讨论】:

  • 我的第一个想法是获取当前事务并使用它来获取锁。但是,我找不到通过@Transactional 开始访问正在进行的事务的方法。因此,我放了这样的东西: Transaction t = graphDatabaseService.beginTx();获得任何交易。但是,我不确定将其放入 Transactional 方法时会发生什么。在日志中,我什至在调试级别上什么也看不到。当我放置它们时,与新事务甚至锁定无关。没有日志,没有错误,我不知道它是否有效,因为它很难检查。
  • @Cob 你找到解决这个案子的方法了吗?目前我遇到了同样的问题,不知道如何获取写锁才能正确更新我的计数器。
猜你喜欢
  • 2015-07-25
  • 1970-01-01
  • 2017-03-26
  • 2015-01-31
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
相关资源
最近更新 更多