1

I have an application that writes to my neo4j database. Immediately after this write, another application performs a query and expects the previously written item as the result.

This doesn't happen, I don't get any result from my query.

Introducing a 100ms artificial delay between the write and the query yields the expected result, but that's not feasible.

I'm writing in TypeScript using neo4j-driver. I'm awaiting every promise the API's throwing at me. I even promisified the session.close function and I await that too (not sure if that does anything).

Is there a cache on neo4j's side that could be at fault? Can I somehow flush it?

kdojeteri
  • 755
  • 6
  • 17
  • 1
    Is this in a cluster? If so you may want to look at [causal clustering](https://neo4j.com/docs/operations-manual/current/clustering/) and [causal chaining](https://neo4j.com/docs/developer-manual/3.4/drivers/sessions-transactions/#driver-transactions-causal-chaining) to be able to guarantee reads of your own writes through usage of bookmarks. Otherwise, if you need this to be absolute, you'll have to introduce synchronization between your reads and writes by locking on the nodes in question before returning them, either with APOC Procedures or writing to the nodes. – InverseFalcon Aug 21 '18 at 06:42
  • @InverseFalcon I'm not sure what you mean by cluster, but I'll definitely check the docs out. So far, causal chaining looks like the way to go. – kdojeteri Aug 21 '18 at 08:15
  • If you're not using a cluster, just a single instance, then this changes things a bit. Neo4j uses read-committed isolation, meaning at the time of the read query, you should be seeing the db with all previously committed transactions. If a transaction is in progress as the start of the read, and has not yet been committed, the read may not see the results of the transaction, or may see some results as portions of the commit are applied to the graph. – InverseFalcon Aug 21 '18 at 08:33
  • If you have a use case which requires you serialize the transactions, only allowing your read transaction to take place after the write is finished (if the write was in progress when you started the read), then you'll need to ensure you take locks upon the nodes and/or relationships in question prior to returning them and their properties. As previously mentioned you can do that either through locking procedures with APOC, or by explicitly writing to the nodes in the question to force acquisition of write locks. Or, if you have a common node to synchronize on, lock on it for both transactions. – InverseFalcon Aug 21 '18 at 08:36
  • I am only using one instance of neo4j. As you said, because neo4j uses read-committed isolation, I should be seeing the results of the write query in the read query that follows immediately after. But that's not happening. I'll go ahead and investigate this further. Thanks for reassuring me that I didn't miss anything obvious, like flushing write buffers or something. – kdojeteri Aug 21 '18 at 18:09
  • CONCLUSION: After spending hours on trying to replicate this issue in a small-scale example, the problem decided to go away by itself. I don't really know what to do with this question now. – kdojeteri Aug 22 '18 at 14:59
  • @InverseFalcon Could you please post your 3 comments as an answer so I can mark this question as solved? Maybe start with something like "If you're not using a cluster, then there's no reason why this shouldn't work" or something along those lines, to tie your answers back to the questions I asked. – kdojeteri Aug 22 '18 at 15:07

0 Answers0