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;
}