How to manually manage Neo4j locks in Spring managed transaction

好久不见. 提交于 2019-12-10 21:24:41

问题


First of all I will explain why I would like to manually set write locks. I use Neo4j database in my web service application based on Spring Data Neo4j. Transactions are managed by Spring, I just use @Transactional annotation. However, I have problem with specific use case which leads to database inconsistency. I have a method that is transactional and its aim is to make such nodes/relation in database:

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

Its algorithm is as follows:

-check if there is a SIM_Card with specific phone number (unique) already in the database (cypher query through @Query),

-if yes get this node and if no create it,

-check if there is any Person attached to this SIM_Card with USES relation (cypher query),

-if there is no such Person create it and attach to SIM_Card.

Unfortunately when there are many requests it happens that I have in database SIM_Cards that are attached to more than one Person. I assume that method is executed by two concurrent threads. Both read database and search for SIM_Card with the same phone number, and both get the information that there is no such SIM_Card in database yet, so they create them, and then they attach two separate Person to them. PhoneNuber is unique for SIM_Card, so eventually there is only one SIM_Card, but two Person remains and it is not expected situation. To fix this I would like to create SIM_Card in separate Transaction and then create Person and attach to this SIM_Card in another transaction. Before the Person is created I will check if there is no Person already attached. However, just before that check I would like to set a write lock manually on SIM_Card and I assume that then other Transaction would not be able to check in meantime if there is/or not any Person connected to this SIM_Card. It would have to wait for the lock to be released and then it will see that this SIM_Card has Person attached and would not create another one.

To achieve that I have to get somehow ability to set Neo4j locks inside @Transactional annotated method and I do not know how to do that. I would really appreciate your help.


回答1:


I think you have to give up @Transactional in this case, wire GraphDatabaseService instance into your repository (or service), and start the transaction and acquire the write lock manually (http://neo4j.com/docs/stable/javadocs/org/neo4j/graphdb/Transaction.html#acquireWriteLock(org.neo4j.graphdb.PropertyContainer)



来源:https://stackoverflow.com/questions/30109292/how-to-manually-manage-neo4j-locks-in-spring-managed-transaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!