public IDbCommand Get(string sql, IDbConnection conn)
{
StringBuilder keyBuilder = DbCaches.StringBuilders.Get();
keyBuilder.Append(sql);
keyBuilder.Append(conn.ConnectionString);
string key = keyBuilder.ToString();
// See if we have one in the cache already.
IDbCommand cmd = null;
lock (_cache)
{
if (_cache.ContainsKey(key))
{
cmd = _cache[key];
// Remove it from the cache so we don't hand it to multiple users.
_cache.Remove(key);
}
}
if (cmd == null)
{
// Make a new one.
cmd = conn.CreateCommand();
// Default timeout is kind of short. There are really two kinds of queries:
// User-caused queries, where we're responding to something the user did, and
// system queries. For user queries, "acceptable" query time is going to be
// way shorter than the timeout anyway, so if the queries are taking very long
// it's a problem way before any reasonable timeout would be reached. System
// queries are from things like the data processing
// jobs, where they're dealing with lots of data and being run behind the scenes,
// so the important thing is just that we DO timeout eventually to prevent a job
// from hanging. So a timeout of several minutes is fine. The CommandTimeout
// attribute is in seconds.
cmd.CommandTimeout = 300;
}
else
{
cmd.Connection = conn;
}
Chronometer.BeginTiming(key);
DbCaches.StringBuilders.Return(keyBuilder);
return cmd;
}