/* * Copy all collections that will be needed to convert masterTxn to this * ReplayTxn. Note that we do not need to copy the openDatabaseHandle * collection. That collection is only needed by an application-facing * Txn, so that those database handles can be invalidated if * needed. ReplayTxn is not application-facing, and uses DatabaseImpls * rather than Databases. */ public void copyDatabasesForConversion(Txn masterTxn) { if (masterTxn.getUndoDatabases() != null) { if (undoDatabases == null) { undoDatabases = new HashMap<DatabaseId, DatabaseImpl>(); } undoDatabases.putAll(masterTxn.getUndoDatabases()); } if (masterTxn.getDeletedDatabases() != null) { if (deletedDatabases == null) { deletedDatabases = new HashSet<DatabaseCleanupInfo>(); } deletedDatabases.addAll(masterTxn.getDeletedDatabases()); } }
@Override protected void close(boolean isCommit) throws DatabaseException { super.close(isCommit); if (activeTxns != null) { Txn removed = activeTxns.remove(getId()); assert removed != null : "txn was not in map " + this + " " + LoggerUtils.getStackTrace(); } }
/** * Get a locker for a write operation. * * @param autoTxnIsReplicated is true if this transaction is executed on a rep group master, and * needs to be broadcast. Currently, all application-created transactions are of the type * com.sleepycat.je.txn.Txn, and are replicated if the parent environment is replicated. Auto * Txns are trickier because they may be created for a local write operation, such as log * cleaning. * @throws IllegalArgumentException via db/cursor read/write methods. */ public static Locker getWritableLocker( Environment env, Transaction userTxn, boolean isInternalDb, boolean dbIsTransactional, boolean autoTxnIsReplicated, TransactionConfig autoCommitConfig) throws DatabaseException { EnvironmentImpl envImpl = DbInternal.getEnvironmentImpl(env); boolean envIsTransactional = envImpl.isTransactional(); if (userTxn == null) { Transaction xaLocker = env.getThreadTransaction(); if (xaLocker != null) { return DbInternal.getLocker(xaLocker); } } if (dbIsTransactional && userTxn == null) { if (autoCommitConfig == null) { autoCommitConfig = DbInternal.getDefaultTxnConfig(env); } return Txn.createAutoTxn( envImpl, autoCommitConfig, (autoTxnIsReplicated ? ReplicationContext.MASTER : ReplicationContext.NO_REPLICATE)); } else if (userTxn == null) { /* Non-transactional user operations use ThreadLocker. */ return ThreadLocker.createThreadLocker(envImpl); } else { /* * The user provided a transaction, the environment and the * database had better be opened transactionally. */ if (!isInternalDb && !envIsTransactional) { throw new IllegalArgumentException( "A Transaction cannot be used because the" + " environment was opened non-transactionally"); } if (!dbIsTransactional) { throw new IllegalArgumentException( "A Transaction cannot be used because the" + " database was opened non-transactionally"); } /* * Use the locker for the given transaction. For read-comitted, * wrap the given transactional locker in a special locker for that * isolation level. */ Locker locker = DbInternal.getLocker(userTxn); if (locker.isReadCommittedIsolation()) { return ReadCommittedLocker.createReadCommittedLocker(envImpl, locker); } return locker; } }