On 12/31/2013 04:12 PM, M. David Allen wrote: > Just curious, what's the thinking behind requiring transactions for reads?
Since nobody else answered yet I'll take a stab at it :-) As far as I know the reason for requiring transaction for read operations is optimization: fetched resources can be released after the transactional context has been closed. A nice side-effect is consistency: your read operations will be unaffected by write transactions that are going on in parallel. > Also, some documentation updates might be appropriate. For example: > > http://api.neo4j.org/current/org/neo4j/graphdb/NotInTransactionException.html > > public class NotInTransactionException > extends RuntimeException <http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html?is-external=true> > > Thrown when attempting to modify the graph outside of a transaction. > Thanks for catching that, the docs have been updated but that spot has been missed. I have opened a pull request for an update of that JavaDoc which has already been merged. > Finally, I noticed that with 2.0, apparently the code wants you to use > try/with, instead of try/finally, e.g. > > |try ( Transaction tx = graphDb.beginTx() ) { blah(); } > > I'm also curious about that decision, since it requires I choose between > looking > at deprecation warnings on my use of tx.finish() or trying to upgrade all my > developer's IDEs to java7 code style compliance. I like the reduction of redundant code this change brings, but then again, I don't have a migrate a (big) code base too it ;-) Johannes > On Tuesday, December 31, 2013 10:07:08 AM UTC-5, Michael Hunger wrote: > > Hi > > Read operation on the database and nodes and relationships now > require transactions > > Probably most sensible to wrap the tx around the entry point to your > service layer. > > HTH > > Michael > > Sent from mobile device > > Am 31.12.2013 um 15:53 schrieb "M. David Allen" <[email protected] > <javascript:>>: > >> I'm in the middle of retrofitting neo4j code that was running on >> 1.9.3 to 2.0.0. This is all happening under windows, jdk1.7.0_45, >> and eclipse. >> >> I expected some teething problems and cut-overs; here's one I've >> run into: >> >> org.neo4j.graphdb.NotInTransactionException >> at >> >> org.neo4j.kernel.impl.persistence.PersistenceManager.getResource(PersistenceManager.java:214) >> at >> >> org.neo4j.kernel.impl.persistence.PersistenceManager.currentKernelTransaction(PersistenceManager.java:84) >> at >> >> org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.transaction(ThreadToStatementContextBridge.java:53) >> at >> >> org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.instance(ThreadToStatementContextBridge.java:47) >> at >> org.neo4j.kernel.impl.core.NodeProxy.hasProperty(NodeProxy.java:346) >> at >> blah.blah.mypackage.MyStorage.isMyObjectNode(Neo4JStorage.java:219) >> at >> blah.blah.mypackage.MyFactory.newObject(Neo4JPLUSObjectFactory.java:190) >> at >> blah.blah.mypackage.MyFactory.listWorkflows(Neo4JStorage.java:933) >> >> I can make it happy by wrapping the methods below in a >> transaction, but I'm pretty sure that's not the right thing to do. >> >> Here's the relevant method: >> >> public static boolean isMyObjectNode(Node n) { >> return n != null && n.hasProperty(PROP_PLUSOBJECT_ID) && >> n.hasProperty(PROP_TYPE) && n.hasProperty(PROP_SUBTYPE); >> } >> >> (Context: all of those PROP_TYPE, etc are all public static final >> String) >> >> The "newObject" method in my package is just creating one of my >> domain objects out of a node. In order to do that, it needs to >> check which kind of node it's dealing with. I'd rather not paste >> that code because it's involved and includes many other subclasses >> that makes the rabbit hole deeper. Suffice to say I'm sure that >> it's just creating my domain objects, and not modifying anything >> in the graph. >> >> The "listWorkflows" method looks like this: >> >> public static List<MyWorkflow> listWorkflows(User user, int >> maxReturn) throws MyException { >> if(maxReturn <= 0 || maxReturn > 1000) maxReturn = 100; >> >> String query = "start n=node:node_auto_index(type=\"" + >> MyWorkflow.TYPE_WORKFLOW + "\") " + >> "where has(n.oid) " + >> "return n " + >> "limit " + maxReturn; >> >> Iterator<Node> ns = Neo4JStorage.execute(query).columnAs("n"); >> ArrayList<MyWorkflow> wfs = new ArrayList<MyWorkflow>(); >> >> while(ns.hasNext()) { >> MyObject o = MyFactory.newObject(ns.next()); >> if(o.isWorkflow()) wfs.add((MyWorkflow)o); >> else { >> log.warning("Returned non-workflow " + o + " from >> workflow query!"); >> } >> } >> >> return wfs; >> } // End listWorkflows >> >> Indeed this code (and its caller) doesn't happen within a >> transaction, but it shouldn't need to -- no modification is going >> on here. >> >> Lastly -- yes, I know about labels, and how labels would probably >> be a better way to do this. I'm planning on exploiting that, but >> the first thing to do is to get the current code base working on >> the new release, and I've got other fish to fry (like cypher query >> syntax updates to get rid of "?") before I get to using labels. >> >> Thanks! >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Neo4j" group. >> To unsubscribe from this group and stop receiving emails from it, >> send an email to [email protected] <javascript:>. >> For more options, visit https://groups.google.com/groups/opt_out >> <https://groups.google.com/groups/opt_out>. > > -- > You received this message because you are subscribed to the Google > Groups "Neo4j" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to [email protected]. > For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "Neo4j" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
