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(-)
----------------------------------------------------------------------