[Mulgara-svn] r1944 - trunk/src/jar/querylang/java/org/mulgara/protocol/http

pag at mulgara.org pag at mulgara.org
Thu Apr 22 18:37:57 UTC 2010


Author: pag
Date: 2010-04-22 11:37:56 -0700 (Thu, 22 Apr 2010)
New Revision: 1944

Modified:
   trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java
Log:
Finer grained protection of transactions in POST operations. This avoids any transactions on read-only operations, or on read operations at the start and end of a set of operations

Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java	2010-04-22 03:49:18 UTC (rev 1943)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java	2010-04-22 18:37:56 UTC (rev 1944)
@@ -54,9 +54,11 @@
 import org.mulgara.query.operation.CreateGraph;
 import org.mulgara.query.operation.Deletion;
 import org.mulgara.query.operation.DropGraph;
+import org.mulgara.query.operation.ExecuteScript;
 import org.mulgara.query.operation.Insertion;
 import org.mulgara.query.operation.Load;
 import org.mulgara.query.operation.Rollback;
+import org.mulgara.query.operation.ServerCommand;
 import org.mulgara.query.operation.SetAutoCommit;
 import org.mulgara.server.ServerInfo;
 import org.mulgara.server.SessionFactoryProvider;
@@ -566,8 +568,29 @@
     List<Command> cmds = getCommand(queryStr, req);
     List<Pair<Answer,Output>> results = new ArrayList<Pair<Answer,Output>>();
 
+    // a flag to indicate that transactions will occur during this operation
     boolean tx = cmds.size() > 1;
-    if (tx) executeCommand(new SetAutoCommit(false), req);
+    // locations in the list of operations for starting and ending transactions
+    int txOn = -1;
+    int txOff = -1;
+    
+    if (tx) {
+      // look for the boundaries of write operations
+      for (int i = 0; i < cmds.size(); i++) {
+        Command c = cmds.get(i);
+        if (c instanceof ServerCommand || c instanceof ExecuteScript) {
+          if (txOn < 0) txOn = i;
+          txOff = i;
+        }
+      }
+      // if there is a single write operation, then no transaction is needed
+      if (txOn == txOff) {
+        txOn = -1;
+        txOff = -1;
+      }
+      // if there is no need to turn transaction on, then turn off the transaction flag
+      tx = txOn >= 0;
+    }
     Object finalResult = null;
     Output finalOutputType = null;
 
@@ -575,11 +598,18 @@
     Output tmpOutputType = null;
     try {
       try {
-        for (Command cmd: cmds) {
+        for (int i = 0; i < cmds.size(); i++) {
+          Command cmd = cmds.get(i);
           // if a transaction is being created, we need to know about it
           if (!tx && cmd instanceof SetAutoCommit) {
             tx = !((SetAutoCommit)cmd).isOn();
           }
+          // test if we need to start our own transaction wrapper here
+          if (i == txOn) {
+            executeCommand(new SetAutoCommit(false), req);
+            tx = true;  // make sure this is set in case another operation reset it
+          }
+
           tmpResult = executeCommand(cmd, req);
           tmpOutputType = getOutputType(req, cmd);
           // remember the last answer we see
@@ -588,6 +618,12 @@
             finalResult = tmpResult;
             finalOutputType = tmpOutputType;
           }
+          
+          // test if we need to end our own transaction wrapper here
+          if (i == txOff) {
+            executeCommand(new SetAutoCommit(true), req);
+            tx = false;  // we can now avoid transactions since we've explicitly closed it
+          }
         }
       } catch (ServletException e) {
         if (tx) executeCommand(new Rollback(), req);




More information about the Mulgara-svn mailing list