public abstract CreateNewConnection ( ) : |
||
return |
/// <summary> /// This returns a connection from the cache, or creates a new one if necessary. /// /// This method is thread safe. /// /// This method improved one test's performance (the only one I measured) by about 20%. /// /// Since some databases cannot have more than one connection at a time, we ask the /// connection descriptor whether we can actually cache the connection or not. /// </summary> public IDbConnection Get(AbstractSqlConnectionDescriptor connDesc) { IDbConnection conn = null; if (connDesc.UsePooling()) { // If it is a pooled connection, check if we have one in our cache. lock (_cache) { if (_cache.ContainsKey(connDesc)) { TimestampedData<IDbConnection> connFromCache = _cache[connDesc]; // This pool only caches one connection for a connection string. _cache.Remove(connDesc); // Don't reuse a connection that was cached more than 5 minutes ago. We use // this cache to handle the case of thousands per second, if we're querying // every 5 minutes we can take the time to create a new connection. if (connFromCache.Time.Ticks < (DateTime.Now.Ticks - 3000000000)) { try { connFromCache.Data.Close(); } catch (Exception e) { _log.Debug("Exception while closing a connection that was probably expired anyway: " + connDesc, e); } } else { conn = connFromCache.Data; } } } } // If it's a bad/broken/something connection, we want a new one also. if ((conn == null) || (conn.State != ConnectionState.Open)) { // Make a new one and put it in the cache. conn = connDesc.CreateNewConnection(); try { conn.Open(); if (_log.IsDebugEnabled) { _log.Debug("Opened connection to: " + connDesc); } lock (_errorCount) { _errorCount[connDesc] = 0; } } catch (Exception e) { // Increment the number of consecutive failures. int newCount = 1; lock (_errorCount) { if (_errorCount.ContainsKey(connDesc)) { newCount = _errorCount[connDesc] + 1; } _errorCount[connDesc] = newCount; } throw new UnableToConnectException(connDesc, newCount, e); } } return conn; }