Skip to content
This repository has been archived by the owner on Jan 28, 2018. It is now read-only.

Transactions in async environment don't work #3

Open
joewhite86 opened this issue Feb 27, 2014 · 6 comments
Open

Transactions in async environment don't work #3

joewhite86 opened this issue Feb 27, 2014 · 6 comments

Comments

@joewhite86
Copy link
Owner

I discovered a serios bug regarding transactions in the asynchronous node environment.
It first hit me when multiple users called methods simultaneously that led to wrong transaction assignments.

I'm currently working on a solution, there are a few options left.

@MatAtBread
Copy link

Can you point me at the area of the code where you see the problem? I'm interested in how it might impact my fork (which is now quite a way from you initial impl, so it may not exist in my build)

@joewhite86
Copy link
Owner Author

The problem hits the complete implementation. As long as you haven't managed, to bind every call inside a transaction to the same JVM Thread, I see no way atm to get this working.

@MatAtBread
Copy link

Ah OK. I did come across that one and pushed all the transactional stuff down into Java to avoid it (basically I have a call that accepts an array of queries and params all inside one transaction). It's not clever but it does work. Although I didn't try, it might be possible with async calls.

@joewhite86
Copy link
Owner Author

I thought about building a stack of calls, too. But that does only work with queries, right?
https://github.com/joewhite86/neo4j-embedded-example here's an example of how I do it right now.
The application logic is now written in java and used as a service inside node.
This approach is even faster than using neo4j-embedded.

@MatAtBread
Copy link

Yes, it pretty much only works with queries, unless you know of some way of getting Java to callback JS (for the intermediate steps between DB calls in a transaction). Our approach (in the end) was basically cypher-based with some addition helper calls like non-destructively updating a bunch of properties in a single call to avoid the JS/Java marshalling overhead, so I extended the existing call set rather than go for a big re-write.

The other change in approach is to give it a more JS "object" interface - we use labels and types to specify JS classes and use Object.create() to instantiate results from the DB (specifically for nodes , paths and relationships) as well as bundling up all of PropertyContainers info (it's ID, labels, etc) so once returned to JS there are many fewer calls across the JS/Java boundary - very similar to your JavascriptContainer. The object format also serializes really well so we can access the DB locally or wrapped in a tiny nodejs wrapper and so get to it remotely with exactly the same JS API.

Rather than promises, we use nodent for the async JS stuff (similar, but done at load time). It also maps better to the ES6 generator/yield model.

And your JavaMapper class is similar in function to our updated code - we found lots of issues with array parameters.

Finally, our approach to the ExecuctionEngine instantiation is simply a ConcurrentHashMap<GraphDatabaseService,ExecutionEngine> internally. That one helped performance a lot.

@MatAtBread
Copy link

...FYI, I'm happy to share it, but it got a bit application specific around the Object.create() stuff, so I thought it was probably not of much help. I probably should have posted the major issues I came across though

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants