diff options
author | Bernard Normier <bernard@zeroc.com> | 2007-12-12 12:03:04 -0500 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2007-12-12 12:03:04 -0500 |
commit | 28c22de9b812daeffa630656818da6ec5411a7da (patch) | |
tree | a3b5142c2144ead6aafb62dd71baf0657296e014 /java/src/Freeze/SharedDbEnv.java | |
parent | Fixed bug #2546 (diff) | |
download | ice-28c22de9b812daeffa630656818da6ec5411a7da.tar.bz2 ice-28c22de9b812daeffa630656818da6ec5411a7da.tar.xz ice-28c22de9b812daeffa630656818da6ec5411a7da.zip |
Fixed bug #2557 (closing database within transaction)
Diffstat (limited to 'java/src/Freeze/SharedDbEnv.java')
-rw-r--r-- | java/src/Freeze/SharedDbEnv.java | 402 |
1 files changed, 237 insertions, 165 deletions
diff --git a/java/src/Freeze/SharedDbEnv.java b/java/src/Freeze/SharedDbEnv.java index d8dabe8a385..807b7ac88b7 100644 --- a/java/src/Freeze/SharedDbEnv.java +++ b/java/src/Freeze/SharedDbEnv.java @@ -23,34 +23,81 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable result = (SharedDbEnv)_map.get(key); if(result == null) { + result = new SharedDbEnv(key, dbEnv); + + Object previousValue = _map.put(key, result); + assert(previousValue == null); + } + else + { + result._refCount++; + } + } + + return result; + } + + // + // Returns a shared map Db; the caller should NOT close this Db. + // + MapDb getSharedMapDb(String dbName, String key, String value, + java.util.Comparator comparator, Map.Index[] indices, java.util.Map indexComparators, + boolean createDb) + { + if(dbName.equals(_catalog.dbName())) + { + _catalog.checkTypes(key, value); + return _catalog; + } + else if(dbName.equals(_catalogIndexList.dbName())) + { + _catalogIndexList.checkTypes(key, value); + return _catalogIndexList; + } + + synchronized(_sharedDbMap) + { + MapDb db = _sharedDbMap.get(dbName); + if(db == null) + { + ConnectionI insertConnection = (ConnectionI)Util.createConnection(_key.communicator, _key.envName); + try { - result = new SharedDbEnv(key, dbEnv); + db = new MapDb(insertConnection, dbName, key, value, comparator, indices, indexComparators, createDb); } - catch(com.sleepycat.db.DatabaseException dx) + finally { - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = errorPrefix(envName) + "creation: " + dx.getMessage(); - throw ex; + insertConnection.close(); } - Object previousValue = _map.put(key, result); + Object previousValue = _sharedDbMap.put(dbName, db); assert(previousValue == null); } else { - result._refCount++; + db.checkTypes(key, value); + db.connectIndices(indices); } + return db; } + } - // - // Make sure the result if fully initialized - // - result.init(); - return result; + // + // Tell SharedDbEnv to close and remove this Shared Db from the map + // + void removeSharedMapDb(String dbName) + { + synchronized(_sharedDbMap) + { + MapDb db = _sharedDbMap.remove(dbName); + if(db != null) + { + db.close(); + } + } } - + public String getEnvName() { @@ -68,20 +115,7 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable { return _dbEnv; } - - public SharedDb - getCatalog() - { - return _catalog; - } - - public SharedDb - getCatalogIndexList() - { - return _catalogIndexList; - } - - + public void close() { @@ -96,66 +130,9 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable assert(value == this); // - // Join thread - // - synchronized(this) - { - _done = true; - notify(); - } - - for(;;) - { - if(_thread != null) - { - try - { - _thread.join(); - _thread = null; - break; - } - catch(InterruptedException ex) - { - } - } - } - - // - // Release catalogs - // - if(_catalog != null) - { - _catalog.close(); - _catalog = null; - } - - if(_catalogIndexList != null) - { - _catalogIndexList.close(); - _catalogIndexList = null; - } - - if(_trace >= 1) - { - _key.communicator.getLogger().trace("Freeze.DbEnv", "closing database environment \"" + - _key.envName + "\""); - } - - // - // Keep lock to prevent somebody else from re-opening this DbEnv - // before it's closed. + // Cleanup with _map locked to prevent concurrent cleanup of the same dbEnv // - try - { - _dbEnv.close(); - } - catch(com.sleepycat.db.DatabaseException dx) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = errorPrefix(_key.envName) + "close: " + dx.getMessage(); - throw ex; - } + cleanup(); } } } @@ -287,7 +264,6 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable private SharedDbEnv(MapKey key, com.sleepycat.db.Environment dbEnv) - throws com.sleepycat.db.DatabaseException { _key = key; _dbEnv = dbEnv; @@ -296,104 +272,198 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable Ice.Properties properties = key.communicator.getProperties(); _trace = properties.getPropertyAsInt("Freeze.Trace.DbEnv"); - if(_ownDbEnv) + try { - com.sleepycat.db.EnvironmentConfig config = new com.sleepycat.db.EnvironmentConfig(); + if(_ownDbEnv) + { + com.sleepycat.db.EnvironmentConfig config = new com.sleepycat.db.EnvironmentConfig(); + + config.setErrorHandler(this); + config.setInitializeLocking(true); + config.setInitializeLogging(true); + config.setInitializeCache(true); + config.setAllowCreate(true); + config.setTransactional(true); - config.setErrorHandler(this); - config.setInitializeLocking(true); - config.setInitializeLogging(true); - config.setInitializeCache(true); - config.setAllowCreate(true); - config.setTransactional(true); + // + // Deadlock detection + // + config.setLockDetectMode(com.sleepycat.db.LockDetectMode.YOUNGEST); - // - // Deadlock detection - // - config.setLockDetectMode(com.sleepycat.db.LockDetectMode.YOUNGEST); + String propertyPrefix = "Freeze.DbEnv." + _key.envName; + if(properties.getPropertyAsInt(propertyPrefix + ".DbRecoverFatal") != 0) + { + config.setRunFatalRecovery(true); + } + else + { + config.setRunRecovery(true); + } - String propertyPrefix = "Freeze.DbEnv." + _key.envName; - if(properties.getPropertyAsInt(propertyPrefix + ".DbRecoverFatal") != 0) + if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".DbPrivate", 1) != 0) + { + config.setPrivate(true); + } + + if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".OldLogsAutoDelete", 1) != 0) + { + config.setLogAutoRemove(true); + } + + if(_trace >= 1) + { + _key.communicator.getLogger().trace("Freeze.DbEnv", "opening database environment \"" + + _key.envName + "\""); + } + + try + { + String dbHome = properties.getPropertyWithDefault(propertyPrefix + ".DbHome", _key.envName); + java.io.File home = new java.io.File(dbHome); + _dbEnv = new com.sleepycat.db.Environment(home, config); + } + catch(java.io.FileNotFoundException dx) + { + NotFoundException ex = new NotFoundException(); + ex.initCause(dx); + ex.message = errorPrefix(_key.envName) + "open: " + dx.getMessage(); + throw ex; + } + + // + // Default checkpoint period is every 120 seconds + // + _checkpointPeriod = + properties.getPropertyAsIntWithDefault(propertyPrefix + ".CheckpointPeriod", 120) * 1000; + + _kbyte = properties.getPropertyAsIntWithDefault(propertyPrefix + ".PeriodicCheckpointMinSize", 0); + + String threadName; + String programName = properties.getProperty("Ice.ProgramName"); + if(programName.length() > 0) + { + threadName = programName + "-"; + } + else + { + threadName = ""; + } + threadName += "FreezeCheckpointThread(" + _key.envName + ")"; + + if(_checkpointPeriod > 0) + { + _thread = new Thread(this, threadName); + _thread.start(); + } + } + + _catalog = new MapDb(_key.communicator, _key.envName, Util.catalogName(), "string", "::Freeze::CatalogData", _dbEnv); + _catalogIndexList = new MapDb(_key.communicator, _key.envName, Util.catalogIndexListName(), + "string", "::Ice::StringSeq", _dbEnv); + } + catch(com.sleepycat.db.DatabaseException dx) + { + cleanup(); + DatabaseException ex = new DatabaseException(); + ex.initCause(dx); + ex.message = errorPrefix(_key.envName) + "creation: " + dx.getMessage(); + throw ex; + } + catch(java.lang.RuntimeException ex) + { + cleanup(); + throw ex; + } + + _refCount = 1; + } + + private void + cleanup() + { + // + // Join thread + // + synchronized(this) + { + _done = true; + notify(); + } + + for(;;) + { + if(_thread != null) { - config.setRunFatalRecovery(true); + try + { + _thread.join(); + _thread = null; + break; + } + catch(InterruptedException ex) + { + } } - else + } + + // + // Release catalogs + // + if(_catalog != null) + { + try { - config.setRunRecovery(true); + _catalog.close(); } - - if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".DbPrivate", 1) != 0) + finally { - config.setPrivate(true); + _catalog = null; } - - if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".OldLogsAutoDelete", 1) != 0) + } + + if(_catalogIndexList != null) + { + try { - config.setLogAutoRemove(true); + _catalogIndexList.close(); } - - if(_trace >= 1) + finally { - _key.communicator.getLogger().trace("Freeze.DbEnv", "opening database environment \"" + - _key.envName + "\""); + _catalogIndexList = null; } - - // - // TODO: FREEZE_DB_MODE - // - + } + + // + // Close Dbs + // + for(MapDb db: _sharedDbMap.values()) + { + db.close(); + } + + if(_trace >= 1) + { + _key.communicator.getLogger().trace("Freeze.DbEnv", "closing database environment \"" + + _key.envName + "\""); + } + + if(_ownDbEnv && _dbEnv != null) + { try { - String dbHome = properties.getPropertyWithDefault(propertyPrefix + ".DbHome", _key.envName); - java.io.File home = new java.io.File(dbHome); - _dbEnv = new com.sleepycat.db.Environment(home, config); + _dbEnv.close(); } - catch(java.io.FileNotFoundException dx) + catch(com.sleepycat.db.DatabaseException dx) { - NotFoundException ex = new NotFoundException(); + DatabaseException ex = new DatabaseException(); ex.initCause(dx); - ex.message = errorPrefix(_key.envName) + "open: " + dx.getMessage(); + ex.message = errorPrefix(_key.envName) + "close: " + dx.getMessage(); throw ex; } - - // - // Default checkpoint period is every 120 seconds - // - _checkpointPeriod = - properties.getPropertyAsIntWithDefault(propertyPrefix + ".CheckpointPeriod", 120) * 1000; - - _kbyte = properties.getPropertyAsIntWithDefault(propertyPrefix + ".PeriodicCheckpointMinSize", 0); - - String threadName; - String programName = properties.getProperty("Ice.ProgramName"); - if(programName.length() > 0) + finally { - threadName = programName + "-"; + _dbEnv = null; } - else - { - threadName = ""; - } - threadName += "FreezeCheckpointThread(" + _key.envName + ")"; - - if(_checkpointPeriod > 0) - { - _thread = new Thread(this, threadName); - _thread.start(); - } - } - - _refCount = 1; - } - - private synchronized void - init() - { - if(_catalog == null) - { - SharedDb[] catalogs = SharedDb.openCatalogs(this); - _catalog = catalogs[0]; - _catalogIndexList = catalogs[1]; } } @@ -438,8 +508,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable private MapKey _key; private com.sleepycat.db.Environment _dbEnv; private boolean _ownDbEnv; - private SharedDb _catalog; - private SharedDb _catalogIndexList; + private MapDb _catalog; + private MapDb _catalogIndexList; private int _refCount = 0; // protected by _map! private boolean _done = false; private int _trace = 0; @@ -449,6 +519,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable private java.util.Map _ctxMap = new java.util.HashMap(); + private java.util.Map<String, MapDb> _sharedDbMap = new java.util.HashMap<String, MapDb>(); + // // Hash map of (MapKey, SharedDbEnv) // |