afs commented on a change in pull request #537: JENA-1676 , JENA-1677: Make the 
commit step more robust against external factors
URL: https://github.com/apache/jena/pull/537#discussion_r261706207
 
 

 ##########
 File path: 
jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/TransactionCoordinator.java
 ##########
 @@ -683,28 +687,80 @@ private boolean promotionWaitForWriters() {
         // Do here because it needs access to the journal.
         notifyPrepareStart(transaction);
         transaction.getComponents().forEach(sysTrans -> {
-            TransactionalComponent c = sysTrans.getComponent() ;
-            ByteBuffer data = c.commitPrepare(transaction) ;
+            ByteBuffer data = sysTrans.commitPrepare() ;
             if ( data != null ) {
-                PrepareState s = new PrepareState(c.getComponentId(), data) ;
+                PrepareState s = new PrepareState(sysTrans.getComponentId(), 
data) ;
                 journal.write(s) ;
             }
         }) ;
         notifyPrepareFinish(transaction);
     }
-
-    /*package*/ void executeCommit(Transaction transaction, Runnable commit, 
Runnable finish) {
+    
+    /*package*/ void executeCommit(Transaction transaction, Runnable commit, 
Runnable finish, Runnable sysabort) {
         if ( transaction.getMode() == ReadWrite.READ ) {
             finish.run();
             notifyCommitFinish(transaction);
             return;
         }
-        
-        // This is the commit for a write transaction  
+        journal.startWrite();
+        try {
+            executeCommitWriter(transaction, commit, finish, sysabort);
+            journal.commitWrite();
+        } catch (TransactionException ex) {
+            throw ex;
+        } catch (Throwable th) {
+            throw th;
+        } finally { journal.endWrite(); }
+    }
+    
+    private void executeCommitWriter(Transaction transaction, Runnable commit, 
Runnable finish, Runnable sysabort) {
         synchronized(coordinatorLock) {
-            // *** COMMIT POINT
-            journal.sync() ;
-            // *** COMMIT POINT
+            try {
+                // Simulate a Thread.interrupt during I/O.
+//                if ( true )
+//                    throw new FileException(new 
ClosedByInterruptException());
+                
+                // *** COMMIT POINT
+                journal.writeJournal(JournalEntry.COMMIT);
+                journal.sync();
+                // *** COMMIT POINT
+            }
+            // catch (ClosedByInterruptException ex) {}
+            // Some low level system error - probably a sign of something 
serious like disk error.
+            catch(FileException ex)  {
+                if ( ex.getCause() instanceof ClosedByInterruptException ) {
+                    // Thread interrupt during java I/O.
+                    // File was closed by java.nio.
+                    // Reopen - this truncates to the last write start 
position.
+                    journal.reopen();
+                    // This call should clear up the transaction state.
+                    rollback(transaction, sysabort);
+                    SysLog.warn("Thread interrupt during I/O in 'commit' : 
executed transaction rollback: "+ex.getMessage());
+                    throw new TransactionException("Thread interrupt during 
I/O in 'commit' : transaction rollback.", ex);
+                }
+                if ( isIOException(ex) )
+                    SysErr.warn("IOException during 'commit' : transaction may 
have committed. Attempting rollback: "+ex.getMessage());
+                else
+                    SysErr.warn("Exception during 'commit' : transaction may 
have committed. Attempting rollback. Details:",ex);
+                if ( abandonTxn(transaction, sysabort) ) {
+                    SysErr.warn("Transaction rollback");
+                    throw new TransactionException("Exception during 'commit' 
- transaction rollback.", ex);
+                }
+                // Very bad. (This have been dealt with already and should get 
to here.)
+                SysErr.error("Transaction rollback failed. System unstable.");
+                throw new TransactionException("Exception during 'rollback' - 
System unstable.", ex);
 
 Review comment:
   There is a good reason why each exception message has different working - 
points to the exact line if they email.
   
   See the [additional 
commit](https://github.com/apache/jena/pull/537/commits/98caf7d4a8792cc1ca4faca4a4cadebcbf25249a)
 that asking the user to contact users@apache.
   
   It isn't prevalent. There would already have been warnings and exceptions 
reported. The main change now is an attempt to handle the situation. 
   
   It happened in our development when Thread.interrupt was called on a long 
running thread that happened at the time to be in a transaction. We have 
stopped using Thread.interrupt - a better mechanism is the pattern used for 
query cancellation. It is the response of the Java I/O close the file 
asynchronously. That is covered further up; it should only impact the journal 
which as some recovery code.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to