/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2006
* Sleepycat Software. All rights reserved.
*
* $Id: Environment.java,v 1.171 2006/01/03 21:55:37 bostic Exp $
*/
package com.sleepycat.je;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import com.sleepycat.je.dbi.DatabaseImpl;
import com.sleepycat.je.dbi.DbEnvPool;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.txn.Locker;
import com.sleepycat.je.txn.LockerFactory;
import com.sleepycat.je.utilint.Tracer;
/**
* Javadoc for this public class is generated
* via the doc templates in the doc_src directory.
*/
public class Environment {
/*
* The name of the je properties file, to be found in the environment
* directory.
*/
private static final String PROPFILE_NAME = "je.properties";
protected EnvironmentImpl environmentImpl;
private TransactionConfig defaultTxnConfig;
private EnvironmentMutableConfig handleConfig;
private Set referringDbs;
private Set referringDbTxns;
private boolean valid;
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public Environment(File envHome, EnvironmentConfig configuration)
throws DatabaseException {
environmentImpl = null;
referringDbs = Collections.synchronizedSet(new HashSet());
referringDbTxns = Collections.synchronizedSet(new HashSet());
valid = false;
DatabaseUtil.checkForNullParam(envHome, "envHome");
/* If the user specified a null object, use the default */
EnvironmentConfig baseConfig =
(configuration == null) ?
EnvironmentConfig.DEFAULT :
configuration;
/* Make a copy, apply je.properties, and init the handle config. */
EnvironmentConfig useConfig = baseConfig.cloneConfig();
applyFileConfig(envHome, useConfig);
copyToHandleConfig(useConfig, useConfig);
/* Look in the shared pool for this environment. */
DbEnvPool.EnvironmentImplInfo envInfo =
DbEnvPool.getInstance().getEnvironment(envHome, useConfig);
environmentImpl = envInfo.envImpl;
/* Check if the environmentImpl is valid. */
environmentImpl.checkIfInvalid();
if (!envInfo.firstHandle && configuration != null) {
/* Perform all environment config updates atomically. */
synchronized (environmentImpl) {
/*
* If a non-null configuration parameter was passed in and this
* is not the handle that created the underlying
* EnvironmentImpl, check that the configuration parameters
* specified for this open match those of the currently open
* environment. An exception is thrown if the check fails.
*
* Don't do this check if this handle created the environment
* because the creation might have modified the parameters,
* which would create a Catch-22 in terms of validation. For
* example, je.maxMemory will be overridden if the JVM's -mx
* flag is less than that setting, so the initial handle's
* config object won't be the same as the passed in config.
*/
environmentImpl.checkImmutablePropsForEquality(useConfig);
}
}
if (!valid) {
valid = true;
}
/* Successful, increment reference count */
environmentImpl.incReferenceCount();
}
/**
* Get an Environment for an existing EnvironmentImpl. Used by utilities
* such as the JMX MBean which don't want to open the environment or be
* reference counted. The calling application must take care not to retain
* the the doc templates in the doc_src directory.
*/
Environment(File envHome)
throws DatabaseException {
environmentImpl = null;
valid = false;
/* Look in the shared pool for this environment. */
DbEnvPool.EnvironmentImplInfo envInfo =
DbEnvPool.getInstance().getExistingEnvironment(envHome);
EnvironmentImpl foundImpl = envInfo.envImpl;
if (foundImpl != null) {
/* Check if the environmentImpl is valid. */
foundImpl.checkIfInvalid();
/* Successful, increment reference count */
environmentImpl = foundImpl;
environmentImpl.incReferenceCount();
/*
* Initialize the handle's environment config, so that it's valid
* to call setConfig and getConfig against this handle. Make a
* copy, apply je.properties, and init the handle config.
*/
EnvironmentConfig useConfig =
EnvironmentConfig.DEFAULT.cloneConfig();
applyFileConfig(envHome, useConfig);
copyToHandleConfig(useConfig, useConfig);
/* Need this in order to open database handles. */
referringDbs = Collections.synchronizedSet(new HashSet());
valid = true;
}
}
/**
* Apply the configurations specified in the je.properties file to override
* any programatically set configurations.
*/
private void applyFileConfig(File envHome,
EnvironmentMutableConfig useConfig)
throws IllegalArgumentException {
/* Apply the je.properties file. */
if (useConfig.getLoadPropertyFile()) {
File paramFile = null;
try {
paramFile = new File(envHome, PROPFILE_NAME);
Properties fileProps = new Properties();
FileInputStream fis = new FileInputStream(paramFile);
fileProps.load(fis);
fis.close();
/* Validate the existing file. */
useConfig.validateProperties(fileProps);
/* Add them to the configuration object. */
Iterator iter = fileProps.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry propPair = (Map.Entry) iter.next();
String name = (String) propPair.getKey();
String value = (String) propPair.getValue();
useConfig.setConfigParam(name, value);
}
} catch (FileNotFoundException e) {
/*
* Klockwork - ok
* Eat the exception, okay if the file doesn't exist.
*/
} catch (IOException e) {
IllegalArgumentException e2 = new IllegalArgumentException
("An error occurred when reading " + paramFile);
e2.initCause(e);
throw e2;
}
}
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public synchronized void close()
throws DatabaseException {
checkHandleIsValid();
try {
checkEnv();
} catch (RunRecoveryException e) {
/*
* We're trying to close on an environment that has seen a fatal
* exception. Try to do the minimum, such as closing file
* descriptors, to support re-opening the environment in the same
* jvm.
*/
if (environmentImpl != null) {
environmentImpl.closeAfterRunRecovery();
}
return;
}
StringBuffer errors = new StringBuffer();
try {
if (referringDbs != null) {
int nDbs = referringDbs.size();
if (nDbs != 0) {
errors.append("There ");
if (nDbs == 1) {
errors.append
("is 1 open Database in the Environment.\n");
} else {
errors.append("are ");
errors.append(nDbs);
errors.append
(" open Database in the Environment.\n");
}
errors.append("Closing the following databases:\n");
Iterator iter = referringDbs.iterator();
while (iter.hasNext()) {
Database db = (Database) iter.next();
/*
* Save the db name before we attempt the close, it's
* unavailable after the close.
*/
String dbName = db.getDebugName();
errors.append(dbName).append(" ");
try {
db.close();
} catch (RunRecoveryException e) {
throw e;
} catch (DatabaseException DBE) {
errors.append("\nWhile closing Database ");
errors.append(dbName);
errors.append(" encountered exception: ");
errors.append(DBE).append("\n");
}
}
}
}
if (referringDbTxns != null) {
int nTxns = referringDbTxns.size();
if (nTxns != 0) {
Iterator iter = referringDbTxns.iterator();
errors.append("There ");
if (nTxns == 1) {
errors.append("is 1 existing transaction opened against");
errors.append(" the Environment.\n");
} else {
errors.append("are ");
errors.append(nTxns);
errors.append(" existing transactions opened against");
errors.append(" the Environment.\n");
}
errors.append("Aborting open transactions ...\n");
while (iter.hasNext()) {
Transaction txn = (Transaction) iter.next();
try {
txn.abort();
} catch (RunRecoveryException e) {
throw e;
} catch (DatabaseException DBE) {
errors.append("\nWhile aborting transaction ");
errors.append(txn.getId());
errors.append(" encountered exception: ");
errors.append(DBE).append("\n");
}
}
}
}
try {
environmentImpl.close();
} catch (RunRecoveryException e) {
throw e;
} catch (DatabaseException DBE) {
errors.append
("\nWhile closing Environment encountered exception: ");
errors.append(DBE).append("\n");
}
} finally {
environmentImpl = null;
valid = false;
if (errors.length() > 0) {
throw new DatabaseException(errors.toString());
}
}
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public synchronized Database openDatabase(Transaction txn,
String databaseName,
DatabaseConfig dbConfig)
throws DatabaseException {
if (dbConfig == null) {
dbConfig = DatabaseConfig.DEFAULT;
}
Database db = new Database(this);
openDb(txn, db, databaseName, dbConfig, false);
return db;
}
/**
* Javadoc for this public class is generated via
* the doc templates in the doc_src directory.
*/
public synchronized
SecondaryDatabase openSecondaryDatabase(Transaction txn,
String databaseName,
Database primaryDatabase,
SecondaryConfig dbConfig)
throws DatabaseException {
if (dbConfig == null) {
dbConfig = SecondaryConfig.DEFAULT;
}
SecondaryDatabase db =
new SecondaryDatabase(this, dbConfig, primaryDatabase);
openDb(txn, db, databaseName, dbConfig, dbConfig.getAllowPopulate());
return db;
}
private void openDb(Transaction txn,
Database newDb,
String databaseName,
DatabaseConfig dbConfig,
boolean needWritableLockerForInit)
throws DatabaseException {
checkEnv();
DatabaseUtil.checkForNullParam(databaseName, "databaseName");
Tracer.trace(Level.FINEST, environmentImpl, "Environment.open: " +
" name=" + databaseName +
" dbConfig=" + dbConfig);
/*
* Check that the open configuration doesn't conflict with the
* environmentImpl configuration.
*/
validateDbConfigAgainstEnv(dbConfig, databaseName);
Locker locker = null;
boolean operationOk = false;
boolean dbIsClosing = false;
try {
/*
* Does this database exist? Get a transaction to use. If the
* database exists already, we really only need a readable locker.
* If the database must be created, we need a writable one.
* Unfortunately, we have to get the readable one first before we
* know whether we have to create. However, if we need to write
* during initialization (to populate a secondary for example),
* then just create a writable locker now.
*/
boolean isWritableLocker;
if (needWritableLockerForInit) {
locker = LockerFactory.getWritableLocker
(this,
txn,
dbConfig.getTransactional(),
true, // retainNonTxnLocks
null);
isWritableLocker = true;
} else {
locker = LockerFactory.getReadableLocker
(this, txn,
dbConfig.getTransactional(),
true, // retainNonTxnLocks
false); // readCommittedIsolation
isWritableLocker = !dbConfig.getTransactional() ||
locker.isTransactional();
}
DatabaseImpl database = environmentImpl.getDb(locker,
databaseName,
newDb);
boolean databaseExists =
(database == null) ? false :
((database.isDeleted()) ? false : true);
if (databaseExists) {
if (dbConfig.getAllowCreate() &&
dbConfig.getExclusiveCreate()) {
/* We intended to create this, but it already exists. */
dbIsClosing = true;
throw new DatabaseException
("Database " + databaseName + " already exists");
}
newDb.initExisting(this, locker, database, dbConfig);
} else {
/* No database. Create if we're allowed to. */
if (dbConfig.getAllowCreate()) {
/*
* We're going to have to do some writing. Switch to a
* writable locker if we don't already have one.
*/
if (!isWritableLocker) {
locker.operationEnd(OperationStatus.SUCCESS);
locker = LockerFactory.getWritableLocker
(this,
txn,
dbConfig.getTransactional(),
true, // retainNonTxnLocks
null);
isWritableLocker = true;
}
newDb.initNew(this, locker, databaseName, dbConfig);
} else {
/* We aren't allowed to create this database. */
throw new DatabaseNotFoundException("Database " +
databaseName +
" not found.");
}
}
operationOk = true;
addReferringHandle(newDb);
} finally {
/*
* Tell the transaction that this operation is over. Some types of
* transactions (BasicLocker and AutoTxn) will actually finish. The
* transaction can decide if it is finishing and if it needs to
* transfer the db handle lock it owns to someone else.
*/
if (locker != null) {
locker.setHandleLockOwner(operationOk, newDb, dbIsClosing);
locker.operationEnd(operationOk);
}
}
}
private void validateDbConfigAgainstEnv(DatabaseConfig dbConfig,
String databaseName)
throws DatabaseException {
/* Check operation's transactional status against the Environment */
if (dbConfig.getTransactional() &&
!(environmentImpl.isTransactional())) {
throw new DatabaseException
("Attempted to open Database " + databaseName +
" transactionally, but parent Environment is" +
" not transactional");
}
/* Check read/write status */
if (environmentImpl.isReadOnly() && (!dbConfig.getReadOnly())) {
throw new DatabaseException
("Attempted to open Database " + databaseName +
" as writable but parent Environment is read only ");
}
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void removeDatabase(Transaction txn,
String databaseName)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
DatabaseUtil.checkForNullParam(databaseName, "databaseName");
Locker locker = null;
boolean operationOk = false;
try {
/*
* Note: use env level isTransactional as proxy for the db
* isTransactional.
*/
locker = LockerFactory.getWritableLocker
(this, txn,
environmentImpl.isTransactional(),
true /*retainNonTxnLocks*/,
null);
environmentImpl.dbRemove(locker, databaseName);
operationOk = true;
} finally {
if (locker != null) {
locker.operationEnd(operationOk);
}
}
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void renameDatabase(Transaction txn,
String databaseName,
String newName)
throws DatabaseException {
DatabaseUtil.checkForNullParam(databaseName, "databaseName");
DatabaseUtil.checkForNullParam(newName, "newName");
checkHandleIsValid();
checkEnv();
Locker locker = null;
boolean operationOk = false;
try {
/*
* Note: use env level isTransactional as proxy for the db
* isTransactional.
*/
locker = LockerFactory.getWritableLocker
(this, txn,
environmentImpl.isTransactional(),
true /*retainNonTxnLocks*/,
null);
environmentImpl.dbRename(locker, databaseName, newName);
operationOk = true;
} finally {
if (locker != null) {
locker.operationEnd(operationOk);
}
}
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public long truncateDatabase(Transaction txn,
String databaseName,
boolean returnCount)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
DatabaseUtil.checkForNullParam(databaseName, "databaseName");
Locker locker = null;
boolean operationOk = false;
long count = 0;
try {
/*
* Note: use env level isTransactional as proxy for the db
* isTransactional.
*/
locker = LockerFactory.getWritableLocker
(this, txn,
environmentImpl.isTransactional(),
true /*retainNonTxnLocks*/,
null);
count = environmentImpl.truncate(locker,
databaseName,
returnCount);
operationOk = true;
} finally {
if (locker != null) {
locker.operationEnd(operationOk);
}
}
return count;
}
/**
* Returns the current memory usage in bytes for all btrees in the
* environmentImpl.
*/
long getMemoryUsage()
throws DatabaseException {
checkHandleIsValid();
checkEnv();
return environmentImpl.getMemoryBudget().getCacheMemoryUsage();
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public File getHome()
throws DatabaseException {
checkHandleIsValid();
return environmentImpl.getEnvironmentHome();
}
/*
* Transaction management
*/
/**
* Returns the default txn config for this environment handle.
*/
TransactionConfig getDefaultTxnConfig() {
return defaultTxnConfig;
}
/**
* Copies the handle properties out of the config properties, and
* initializes the default transaction config.
*/
private void copyToHandleConfig(EnvironmentMutableConfig useConfig,
EnvironmentConfig initStaticConfig)
throws DatabaseException {
/*
* Create the new objects, initialize them, then change the instance
* fields. This avoids synchronization issues.
*/
EnvironmentMutableConfig newHandleConfig =
new EnvironmentMutableConfig();
useConfig.copyHandlePropsTo(newHandleConfig);
this.handleConfig = newHandleConfig;
TransactionConfig newTxnConfig =
TransactionConfig.DEFAULT.cloneConfig();
newTxnConfig.setNoSync(handleConfig.getTxnNoSync());
newTxnConfig.setWriteNoSync(handleConfig.getTxnWriteNoSync());
if (initStaticConfig != null) {
newTxnConfig.setSerializableIsolation
(initStaticConfig.getTxnSerializableIsolation());
newTxnConfig.setReadCommitted
(initStaticConfig.getTxnReadCommitted());
} else {
newTxnConfig.setSerializableIsolation
(defaultTxnConfig.getSerializableIsolation());
newTxnConfig.setReadCommitted
(defaultTxnConfig.getReadCommitted());
}
this.defaultTxnConfig = newTxnConfig;
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public Transaction beginTransaction(Transaction parent,
TransactionConfig txnConfig)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
if (!environmentImpl.isTransactional()) {
throw new DatabaseException
("Transactions can not be used in a non-transactional " +
"environment");
}
if (txnConfig != null &&
((txnConfig.getSerializableIsolation() &&
txnConfig.getReadUncommitted()) ||
(txnConfig.getSerializableIsolation() &&
txnConfig.getReadCommitted()) ||
(txnConfig.getReadUncommitted() &&
txnConfig.getReadCommitted()))) {
throw new IllegalArgumentException
("Only one may be specified: SerializableIsolation, " +
"ReadCommitted or ReadUncommitted");
}
/*
* Apply txn config defaults. We don't need to clone unless we have to
* apply the env default, since we don't hold onto a txn config
* reference.
*/
TransactionConfig useConfig = null;
if (txnConfig == null) {
useConfig = defaultTxnConfig;
} else {
if (defaultTxnConfig.getNoSync() ||
defaultTxnConfig.getWriteNoSync()) {
/*
* The environment sync settings have been set, check if any
* were set in the user's txn config. If none were set in the
* user's config, apply the environment defaults
*/
if (!txnConfig.getNoSync() &&
!txnConfig.getSync() &&
!txnConfig.getWriteNoSync()) {
useConfig = txnConfig.cloneConfig();
if (defaultTxnConfig.getWriteNoSync()) {
useConfig.setWriteNoSync(true);
} else {
useConfig.setNoSync(true);
}
}
}
/* Apply isolation level default. */
if (!txnConfig.getSerializableIsolation() &&
!txnConfig.getReadCommitted() &&
!txnConfig.getReadUncommitted()) {
if (defaultTxnConfig.getSerializableIsolation()) {
if (useConfig == null) {
useConfig = txnConfig.cloneConfig();
}
useConfig.setSerializableIsolation(true);
} else if (defaultTxnConfig.getReadCommitted()) {
if (useConfig == null) {
useConfig = txnConfig.cloneConfig();
}
useConfig.setReadCommitted(true);
}
}
/* No environment level defaults applied. */
if (useConfig == null) {
useConfig = txnConfig;
}
}
Transaction txn =
new Transaction
(this, environmentImpl.txnBegin(parent, useConfig));
addReferringHandle(txn);
return txn;
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void checkpoint(CheckpointConfig ckptConfig)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
CheckpointConfig useConfig =
(ckptConfig == null) ? CheckpointConfig.DEFAULT : ckptConfig;
environmentImpl.invokeCheckpoint(useConfig,
false, // flushAll
"api");
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void sync()
throws DatabaseException {
checkHandleIsValid();
checkEnv();
CheckpointConfig config = new CheckpointConfig();
config.setForce(true);
environmentImpl.invokeCheckpoint(config,
true, // flushAll
"sync");
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public int cleanLog()
throws DatabaseException {
checkHandleIsValid();
checkEnv();
return environmentImpl.invokeCleaner();
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void evictMemory()
throws DatabaseException {
checkHandleIsValid();
checkEnv();
environmentImpl.invokeEvictor();
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void compress()
throws DatabaseException {
checkHandleIsValid();
checkEnv();
environmentImpl.invokeCompressor();
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public EnvironmentConfig getConfig()
throws DatabaseException {
checkHandleIsValid();
EnvironmentConfig config = environmentImpl.cloneConfig();
handleConfig.copyHandlePropsTo(config);
config.fillInEnvironmentGeneratedProps(environmentImpl);
return config;
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void setMutableConfig(EnvironmentMutableConfig mutableConfig)
throws DatabaseException {
checkHandleIsValid();
DatabaseUtil.checkForNullParam(mutableConfig, "mutableConfig");
/*
* Change the mutable properties specified in the given
* configuratation.
*/
environmentImpl.setMutableConfig(mutableConfig);
/* Reset the handle config properties. */
copyToHandleConfig(mutableConfig, null);
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public EnvironmentMutableConfig getMutableConfig()
throws DatabaseException {
checkHandleIsValid();
EnvironmentMutableConfig config = environmentImpl.cloneMutableConfig();
handleConfig.copyHandlePropsTo(config);
return config;
}
/**
* Not public yet, since there's nothing to upgrade.
*/
void upgrade()
throws DatabaseException {
/* Do nothing. Nothing to upgrade yet. */
}
/**
* General stats
*/
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public EnvironmentStats getStats(StatsConfig config)
throws DatabaseException {
StatsConfig useConfig =
(config == null) ? StatsConfig.DEFAULT : config;
if (environmentImpl != null) {
return environmentImpl.loadStats(useConfig);
} else {
return new EnvironmentStats();
}
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public LockStats getLockStats(StatsConfig config)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
StatsConfig useConfig =
(config == null) ? StatsConfig.DEFAULT : config;
return environmentImpl.lockStat(useConfig);
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public TransactionStats getTransactionStats(StatsConfig config)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
StatsConfig useConfig =
(config == null) ? StatsConfig.DEFAULT : config;
return environmentImpl.txnStat(useConfig);
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public List getDatabaseNames()
throws DatabaseException {
checkHandleIsValid();
checkEnv();
return environmentImpl.getDbNames();
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public boolean verify(VerifyConfig config, PrintStream out)
throws DatabaseException {
checkHandleIsValid();
checkEnv();
VerifyConfig useConfig =
(config == null) ? VerifyConfig.DEFAULT : config;
return environmentImpl.verify(useConfig, out);
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public Transaction getThreadTransaction()
throws DatabaseException {
return (Transaction) environmentImpl.getTxnManager().getTxnForThread();
}
/**
* Javadoc for this public method is generated via
* the doc templates in the doc_src directory.
*/
public void setThreadTransaction(Transaction txn) {
environmentImpl.getTxnManager().setTxnForThread(txn);
}
/*
* Non public api -- helpers
*/
/*
* Let the Environment remember what's opened against it.
*/
void addReferringHandle(Database db) {
referringDbs.add(db);
}
/**
* Let the Environment remember what's opened against it.
*/
void addReferringHandle(Transaction txn) {
referringDbTxns.add(txn);
}
/**
* The referring db has been closed.
*/
void removeReferringHandle(Database db) {
referringDbs.remove(db);
}
/**
* The referring Transaction has been closed.
*/
void removeReferringHandle(Transaction txn) {
referringDbTxns.remove(txn);
}
/*
* Debugging aids.
*/
/**
* Internal entrypoint.
*/
EnvironmentImpl getEnvironmentImpl() {
return environmentImpl;
}
protected void checkHandleIsValid()
throws DatabaseException {
if (!valid) {
throw new DatabaseException
("Attempt to use non-open Environment object().");
}
}
/**
* Throws if the environmentImpl is invalid.
*/
protected void checkEnv()
throws DatabaseException, RunRecoveryException {
if (environmentImpl == null) {
return;
}
environmentImpl.checkIfInvalid();
environmentImpl.checkNotClosed();
}
}