Github user afs commented on a diff in the pull request:

    https://github.com/apache/jena/pull/336#discussion_r159746359
  
    --- Diff: 
jena-arq/src/main/java/org/apache/jena/sparql/core/mem/DatasetGraphInMemory.java
 ---
    @@ -146,25 +162,84 @@ private void _begin(ReadWrite readWrite) {
         }
         
         /** Called transaction start code at most once per transaction. */ 
    -    private void startTransaction(ReadWrite mode) {
    -        transactionLock.enterCriticalSection(mode.equals(READ)); // get 
the dataset write lock, if needed.
    -        transactionType(mode);
    +    private void startTransaction(TxnType txnType, ReadWrite mode) {
    +        transactionLock.enterCriticalSection(mode.equals(ReadWrite.READ)); 
// get the dataset write lock, if needed.
    +        transactionType.set(txnType);
    +        transactionMode(mode);
             isInTransaction(true);
         }
     
         /** Called transaction ending code at most once per transaction. */ 
         private void finishTransaction() {
             isInTransaction.remove();
             transactionType.remove();
    +        transactionMode.remove();
             version.remove();
             transactionLock.leaveCriticalSection();
         }
          
    +    @Override
    +    public boolean promote() {
    +        if (!isInTransaction())
    +            throw new JenaTransactionException("Tried to promote outside a 
transaction!");
    +        if ( transactionMode().equals(ReadWrite.WRITE) )
    +            return true;
    +
    +        boolean readCommitted;
    +        // Initial state
    +        switch(transactionType.get()) {
    +            case WRITE :
    +                return true;
    +            case READ :
    +                throw new JenaTransactionException("Tried to promote READ 
transaction");
    +            case READ_COMMITTED_PROMOTE :
    +                readCommitted = true;
    +            case READ_PROMOTE :
    +                readCommitted = false;
    +                // Maybe!
    +                break;
    +            default:
    +                throw new NullPointerException();
    +        }
    +        
    +        try {
    +            _promote(readCommitted);
    +            return true;
    +        } catch (JenaTransactionException ex) {
    +            return false ;
    +        }
    +    }
    +    
    +    private void _promote(boolean readCommited) {
    +        //System.err.printf("Promote: version=%d generation=%d\n", 
version.get() , generation.get()) ;
    +        
    +        // Outside lock.
    +        if ( ! readCommited && version.get() != generation.get() )  {
    --- End diff --
    
    Yes- that's what happens. This part of the code isn't new - only moved. The 
check is done twice, once before the lock, once again after to avoid 
unnecessary `transactionLock` taking.
    
    It's the same algorithm in TDB and TDB2.  TDB and TDB2 have explicit 
`Transaction` objects that carry the start version. The shared tests cover all 
cases.



---

Reply via email to