You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2017/03/13 14:49:32 UTC

[1/2] jena git commit: JENA-1302: Make 2 phase commit safe.

Repository: jena
Updated Branches:
  refs/heads/master 057b6396d -> e07054d79


JENA-1302: Make 2 phase commit safe.

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/9f0a1158
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/9f0a1158
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/9f0a1158

Branch: refs/heads/master
Commit: 9f0a115878857d8219bc3efc263965a4d529512b
Parents: edf8317
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Mar 11 22:03:41 2017 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Mar 11 22:03:41 2017 +0000

----------------------------------------------------------------------
 .../jena/query/text/DatasetGraphText.java       | 128 +++++++++++++------
 1 file changed, 86 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/9f0a1158/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
----------------------------------------------------------------------
diff --git a/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java b/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
index add198a..d0664b8 100644
--- a/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
+++ b/jena-text/src/main/java/org/apache/jena/query/text/DatasetGraphText.java
@@ -35,6 +35,10 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
     private final TextIndex     textIndex ;
     private final Graph         dftGraph ;
     private final boolean       closeIndexOnClose;
+    // Lock needed for commit/abort that perform an index operation and a dataset operation
+    // which need it happen without a W thread coming in between them.
+    // JENA-1302.
+    private final Object        txnExitLock = new Object();
     
     
     // If we are going to implement Transactional, then we are going to have to do as DatasetGraphWithLock and
@@ -100,22 +104,30 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
 
     @Override
     public void begin(ReadWrite readWrite) {
+        // Do not synchronized(txnLock) here. It will deadlock because if there
+        // is an writer in commit, it can't 
+        
+        // The "super.begin" is enough.
         readWriteMode.set(readWrite);
         super.begin(readWrite) ;
         super.getMonitor().start() ;
     }
     
-    /**
-     * Rollback all changes, discarding any exceptions that occur.
-     */
-    @Override
-    public void abort() {
-        // Roll back all both objects, discarding any exceptions that occur
-        try { super.abort(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
-        try { textIndex.rollback(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
-        readWriteMode.set(null) ;
-        super.getMonitor().finish() ;
-    }
+    // JENA-1302 :: txnExitLock
+    // We need to 
+    //   textIndex.prepareCommit();
+    //   super.commit();
+    //   textIndex.commit();
+    // without another thread getting in.
+    
+    // Concurrency control most of the time is because we use the transaction
+    // capability of the wrapped dataset but here we need to do an action before
+    // wrapped dataset commit and also an action after.
+    // 
+    // At the point of super.commit, it let in a new writer in begin() which
+    // races to commit before text index commit.
+    //
+    // txnExitLock extends the time of exclusive access.    
     
     /**
      * Perform a 2-phase commit by first calling prepareCommit() on the TextIndex
@@ -131,32 +143,71 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
      */
     @Override
     public void commit() {
+        if (readWriteMode.get() == ReadWrite.WRITE)
+            commit_W();
+        else
+            commit_R();
+    }
+    
+    
+    private void commit_R() {
+        // No index action needed.
         super.getMonitor().finish() ;
-        // Phase 1
-        if (readWriteMode.get() == ReadWrite.WRITE) {
-            try {
-                textIndex.prepareCommit();
-            }
+        super.commit();
+        readWriteMode.set(null);
+    }
+
+    private void commit_W() {
+        synchronized(txnExitLock) {
+            super.getMonitor().finish() ;
+            // Phase 1
+            try { textIndex.prepareCommit(); }
             catch (Throwable t) {
                 log.error("Exception in prepareCommit: " + t.getMessage(), t) ;
                 abort();
                 throw new TextIndexException(t);
             }
-        }
-        
-        // Phase 2
-        try {
-            super.commit();
-            if (readWriteMode.get() == ReadWrite.WRITE) {
+            
+            // Phase 2
+            try {
+                super.commit();
                 textIndex.commit();
             }
+            catch (Throwable t) {
+                log.error("Exception in commit: " + t.getMessage(), t) ;
+                abort();
+                throw new TextIndexException(t);
+            }
+            readWriteMode.set(null);
         }
-        catch (Throwable t) {
-            log.error("Exception in commit: " + t.getMessage(), t) ;
-            abort();
-            throw new TextIndexException(t);
+    }
+
+    /**
+     * Rollback all changes, discarding any exceptions that occur.
+     */
+    @Override
+    public void abort() {
+        if (readWriteMode.get() == ReadWrite.WRITE)
+            abort_W();
+        else
+            abort_R();
+    }
+    
+    private void abort_R() {
+        super.getMonitor().finish() ;
+        try { super.abort() ; }
+        catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
+        readWriteMode.set(null) ;
+    }
+    
+    private void abort_W() {
+        synchronized(txnExitLock) {
+            super.getMonitor().finish() ;
+            // Roll back on both objects, discarding any exceptions that occur
+            try { super.abort(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
+            try { textIndex.rollback(); } catch (Throwable t) { log.warn("Exception in abort: " + t.getMessage(), t); }
+            readWriteMode.set(null) ;
         }
-        readWriteMode.set(null);
     }
 
     @Override
@@ -166,25 +217,18 @@ public class DatasetGraphText extends DatasetGraphMonitor implements Transaction
 
     @Override
     public void end() {
-        // If we are still in a write transaction at this point, then commit was never called, so rollback the TextIndex
-        if (readWriteMode.get() == ReadWrite.WRITE) {
-            try {
-                textIndex.rollback();
-            }
-            catch (Throwable t) {
-                log.warn("Exception in end: " + t.getMessage(), t) ;
-            }
-        }
-        
-        try {
+        if ( ! isInTransaction() ) {
             super.end() ;
+            return;
         }
-        catch (Throwable t) {
-            log.warn("Exception in end: " + t.getMessage(), t) ;
+        if (readWriteMode.get() == ReadWrite.WRITE) {
+            // If we are still in a write transaction at this point, then commit
+            // was never called, so rollback the TextIndex and the dataset.
+            abort();
         }
-        
-        readWriteMode.set(null) ;
+        super.end() ;
         super.getMonitor().finish() ;
+        readWriteMode.set(null) ;
     }
     
     @Override


[2/2] jena git commit: JENA-1302: Merge commit 'refs/pull/225/head' of github.com:apache/jena

Posted by an...@apache.org.
JENA-1302: Merge commit 'refs/pull/225/head' of github.com:apache/jena

This closes #225.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/e07054d7
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/e07054d7
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/e07054d7

Branch: refs/heads/master
Commit: e07054d79bee975e8e1dff4bc8c31fd3f2d4fc49
Parents: 057b639 9f0a115
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Mar 13 14:38:26 2017 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Mar 13 14:38:26 2017 +0000

----------------------------------------------------------------------
 .../jena/query/text/DatasetGraphText.java       | 128 +++++++++++++------
 1 file changed, 86 insertions(+), 42 deletions(-)
----------------------------------------------------------------------