【发布时间】: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 锁,但我不知道该怎么做。非常感谢您的帮助。
【问题讨论】:
-
你找到解决这个案子的方法了吗?目前我遇到了同样的问题,不知道如何获取写锁才能正确更新我的计数器。
-
请考虑我的问题:stackoverflow.com/questions/50665958/…
@Transactional具有isolation属性,这可能会有所帮助。但不幸的是,如果此设置偏离默认值,Neo4jTransactionManager会在doBegin()方法中引发异常:github.com/spring-projects/spring-data-neo4j/blob/master/… -
总之,多年以来从未实施过合理的支持:github.com/neo4j/neo4j/issues/1103