diff options
Diffstat (limited to 'src')
6 files changed, 56 insertions, 24 deletions
| diff --git a/src/main/java/com/amazon/carbonado/IsolationLevel.java b/src/main/java/com/amazon/carbonado/IsolationLevel.java index 7571205..fc8c747 100644 --- a/src/main/java/com/amazon/carbonado/IsolationLevel.java +++ b/src/main/java/com/amazon/carbonado/IsolationLevel.java @@ -48,6 +48,12 @@ package com.amazon.carbonado;  public enum IsolationLevel {
      /**
 +     * Indicates that no actual transaction is in progress. If this level is
 +     * specified when entering a transaction, it uses auto-commit mode.
 +     */
 +    NONE,
 +
 +    /**
       * Indicates that dirty reads, non-repeatable reads and phantom reads can
       * occur. This level allows modifications by one transaction to be read by
       * another transaction before any changes have been committed (a "dirty
 diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java index 80ad172..bb17067 100644 --- a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java +++ b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java @@ -296,14 +296,10 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {      void populateIndex(Repository repo, Storage<S> masterStorage) throws RepositoryException {
          MergeSortBuffer buffer;
          Comparator c;
 -        Transaction txn;
 -
 -        if (repo.getTransactionIsolationLevel() == null) {
 -            txn = null;
 -        } else {
 -            txn = repo.enterTopTransaction(IsolationLevel.READ_COMMITTED);
 -        }
 +        // Enter top transaction with isolation level of none to make sure
 +        // preload operation does not run in a long nested transaction.
 +        Transaction txn = repo.enterTopTransaction(IsolationLevel.NONE);
          try {
              Cursor<S> cursor = masterStorage.query().fetch();
              if (!cursor.hasNext()) {
 @@ -335,10 +331,10 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {              while (cursor.hasNext()) {
                  buffer.add(makeIndexEntry(cursor.next()));
              }
 +
 +            // No need to commit transaction because no changes should have been made.
          } finally {
 -            if (txn != null) {
 -                txn.exit();
 -            }
 +            txn.exit();
          }
          buffer.sort();
 diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCRepository.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCRepository.java index 3a6ec68..f9c6d25 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCRepository.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCRepository.java @@ -79,7 +79,9 @@ public class JDBCRepository      static IsolationLevel mapIsolationLevelFromJdbc(int jdbcLevel) {
          switch (jdbcLevel) {
 -        case Connection.TRANSACTION_READ_UNCOMMITTED: default:
 +        case Connection.TRANSACTION_NONE: default:
 +            return IsolationLevel.NONE;
 +        case Connection.TRANSACTION_READ_UNCOMMITTED:
              return IsolationLevel.READ_UNCOMMITTED;
          case Connection.TRANSACTION_READ_COMMITTED:
              return IsolationLevel.READ_COMMITTED;
 @@ -92,7 +94,9 @@ public class JDBCRepository      static int mapIsolationLevelToJdbc(IsolationLevel level) {
          switch (level) {
 -        case READ_UNCOMMITTED: default:
 +        case NONE: default:
 +            return Connection.TRANSACTION_NONE;
 +        case READ_UNCOMMITTED:
              return Connection.TRANSACTION_READ_UNCOMMITTED;
          case READ_COMMITTED:
              return Connection.TRANSACTION_READ_COMMITTED;
 @@ -513,9 +517,14 @@ public class JDBCRepository              // Get connection outside synchronized section since it may block.
              Connection con = mDataSource.getConnection();
 -            con.setAutoCommit(false);
 -            if (level != mDefaultIsolationLevel) {
 -                con.setTransactionIsolation(mapIsolationLevelToJdbc(level));
 +
 +            if (level == IsolationLevel.NONE) {
 +                con.setAutoCommit(true);
 +            } else {
 +                con.setAutoCommit(false);
 +                if (level != mDefaultIsolationLevel) {
 +                    con.setTransactionIsolation(mapIsolationLevelToJdbc(level));
 +                }
              }
              synchronized (mAllTxnMgrs) {
 @@ -609,6 +618,8 @@ public class JDBCRepository          }
          switch (desiredLevel) {
 +        case NONE:
 +            return IsolationLevel.NONE;
          case READ_UNCOMMITTED:
              return mReadUncommittedLevel;
          case READ_COMMITTED:
 diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java index d92228d..832745b 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java @@ -34,10 +34,12 @@ import com.amazon.carbonado.IsolationLevel;   * @author Brian S O'Neill
   */
  class JDBCTransaction {
 +    // Use this magic value to indicate that the isolation level need not be
 +    // changed when the transaction ends. This is a little optimization to
 +    // avoid a round trip call to the remote database.
 +    private static final int LEVEL_NOT_CHANGED = -1;
 +
      private final Connection mConnection;
 -    // Use TRANSACTION_NONE as a magic value to indicate that the isolation
 -    // level need not be changed when the transaction ends. This is a little
 -    // optimization to avoid a round trip call to the remote database.
      private final int mOriginalLevel;
      private Savepoint mSavepoint;
 @@ -46,7 +48,7 @@ class JDBCTransaction {      JDBCTransaction(Connection con) {
          mConnection = con;
          // Don't change level upon abort.
 -        mOriginalLevel = Connection.TRANSACTION_NONE;
 +        mOriginalLevel = LEVEL_NOT_CHANGED;
      }
      /**
 @@ -57,16 +59,19 @@ class JDBCTransaction {          if (level == null) {
              // Don't change level upon abort.
 -            mOriginalLevel = Connection.TRANSACTION_NONE;
 +            mOriginalLevel = LEVEL_NOT_CHANGED;
          } else {
              int newLevel = JDBCRepository.mapIsolationLevelToJdbc(level);
              int originalLevel = mConnection.getTransactionIsolation();
              if (newLevel == originalLevel) {
                  // Don't change level upon abort.
 -                mOriginalLevel = Connection.TRANSACTION_NONE;
 +                mOriginalLevel = LEVEL_NOT_CHANGED;
              } else {
 -                // Don't change level upon abort.
 +                // Do change level upon abort.
                  mOriginalLevel = originalLevel;
 +                if (originalLevel == Connection.TRANSACTION_NONE) {
 +                    mConnection.setAutoCommit(false);
 +                }
                  mConnection.setTransactionIsolation(newLevel);
              }
          }
 @@ -105,8 +110,12 @@ class JDBCTransaction {              return mConnection;
          } else {
              mConnection.rollback(mSavepoint);
 -            if (mOriginalLevel != Connection.TRANSACTION_NONE) {
 -                mConnection.setTransactionIsolation(mOriginalLevel);
 +            if (mOriginalLevel != LEVEL_NOT_CHANGED) {
 +                if (mOriginalLevel == Connection.TRANSACTION_NONE) {
 +                    mConnection.setAutoCommit(true);
 +                } else {
 +                    mConnection.setTransactionIsolation(mOriginalLevel);
 +                }
              }
              mSavepoint = null;
              return null;
 diff --git a/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBTransactionManager.java b/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBTransactionManager.java index 4c6105f..53ca5e4 100644 --- a/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBTransactionManager.java +++ b/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBTransactionManager.java @@ -49,6 +49,9 @@ class BDBTransactionManager<Txn> extends TransactionManager<Txn> {      }
      protected Txn createTxn(Txn parent, IsolationLevel level) throws Exception {
 +        if (level == IsolationLevel.NONE) {
 +            return null;
 +        }
          return repository().txn_begin(parent, level);
      }
 @@ -56,6 +59,9 @@ class BDBTransactionManager<Txn> extends TransactionManager<Txn> {      protected Txn createTxn(Txn parent, IsolationLevel level, int timeout, TimeUnit unit)
          throws Exception
      {
 +        if (level == IsolationLevel.NONE) {
 +            return null;
 +        }
          if (timeout == 0) {
              return repository().txn_begin_nowait(parent, level);
          } else {
 diff --git a/src/main/java/com/amazon/carbonado/spi/TransactionManager.java b/src/main/java/com/amazon/carbonado/spi/TransactionManager.java index 144b411..e8cc637 100644 --- a/src/main/java/com/amazon/carbonado/spi/TransactionManager.java +++ b/src/main/java/com/amazon/carbonado/spi/TransactionManager.java @@ -304,6 +304,8 @@ public abstract class TransactionManager<Txn> {       *
       * @param parent optional parent transaction
       * @param level required isolation level
 +     * @return new transaction, parent transaction, or possibly null if required
 +     * isolation level is none
       */
      protected abstract Txn createTxn(Txn parent, IsolationLevel level) throws Exception;
 @@ -320,6 +322,8 @@ public abstract class TransactionManager<Txn> {       * @param level required isolation level
       * @param timeout desired timeout for lock acquisition, never negative
       * @param unit timeout unit, never null
 +     * @return new transaction, parent transaction, or possibly null if required
 +     * isolation level is none
       */
      protected Txn createTxn(Txn parent, IsolationLevel level,
                              int timeout, TimeUnit unit)
 | 
