Skip to content

Commit f3d1725

Browse files
author
Mike Doerfler
committed
Synch with H2.0.3 - main thing is the addition of a basic connection pool
to DriverManager so you can get back the same IDbConnection (same by reference - not just an already established connection by the data providers built in connection pool). This defaults to not being on. SVN: trunk@584
1 parent 9c30866 commit f3d1725

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

src/NHibernate/Connection/ConnectionProvider.cs

+26-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ namespace NHibernate.Connection
1010
/// <summary>
1111
/// The base class for the ConnectionProvider.
1212
/// </summary>
13-
public abstract class ConnectionProvider : IConnectionProvider
13+
public abstract class ConnectionProvider : IConnectionProvider, IDisposable
1414
{
1515
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(ConnectionProvider));
1616
private string connString = null;
17+
private int poolSize;
1718
protected IDriver driver = null;
1819

1920
public virtual void CloseConnection(IDbConnection conn)
@@ -37,6 +38,14 @@ public virtual void CloseConnection(IDbConnection conn)
3738
public virtual void Configure(IDictionary settings)
3839
{
3940
log.Info("Configuring ConnectionProvider");
41+
42+
// default the poolSize to 0 if no setting was made because most of the .net DataProvider
43+
// do their own connection pooling. This would be useful to change to some higher number
44+
// if the .net DataProvider did not provide their own connection pooling. I don't know of
45+
// any instances of this yet.
46+
poolSize = PropertiesHelper.GetInt(Cfg.Environment.PoolSize, Cfg.Environment.Properties, 0);
47+
log.Info("NHibernate connection pool size: " + poolSize);
48+
4049
connString = Cfg.Environment.Properties[ Cfg.Environment.ConnectionString ] as string;
4150
if (connString==null) throw new HibernateException("Could not find connection string setting");
4251

@@ -74,6 +83,11 @@ protected virtual string ConnectionString
7483
get { return connString;}
7584
}
7685

86+
protected virtual int PoolSize
87+
{
88+
get { return poolSize; }
89+
}
90+
7791
public IDriver Driver
7892
{
7993
get {return driver;}
@@ -87,5 +101,16 @@ public IDriver Driver
87101

88102
public abstract bool IsStatementCache {get;}
89103

104+
public abstract void Close();
105+
106+
#region IDisposable Members
107+
108+
// equiv to java's object.finalize()
109+
public void Dispose()
110+
{
111+
Close();
112+
}
113+
114+
#endregion
90115
}
91116
}

src/NHibernate/Connection/DriverConnectionProvider.cs

+67-1
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
using System;
2+
using System.Collections;
23
using System.Data;
34

45
using NHibernate.Driver;
56

67
namespace NHibernate.Connection
78
{
89
/// <summary>
9-
/// Summary description for DriverConnectionProvider.
10+
/// A ConnectionProvider that uses an IDriver to create connections.
1011
/// </summary>
12+
/// <remarks>
13+
/// This IConnectionProvider implements a rudimentary connection pool.
14+
/// </remarks>
1115
public class DriverConnectionProvider : ConnectionProvider
1216
{
1317
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(DriverConnectionProvider));
18+
private static object poolLock = new object();
19+
private readonly ArrayList pool = new ArrayList();
20+
21+
private int checkedOut = 0;
1422

1523
public DriverConnectionProvider()
1624
{
@@ -19,6 +27,25 @@ public DriverConnectionProvider()
1927

2028
public override IDbConnection GetConnection()
2129
{
30+
if(log.IsDebugEnabled) log.Debug("total checked-out connections: " + checkedOut);
31+
32+
lock(poolLock)
33+
{
34+
if( pool.Count > 0 )
35+
{
36+
int last = pool.Count - 1;
37+
if(log.IsDebugEnabled)
38+
{
39+
log.Debug("using pooled connection, pool size: " + last);
40+
checkedOut++;
41+
}
42+
43+
IDbConnection conn = (IDbConnection)pool[last];
44+
pool.RemoveAt(last);
45+
return conn;
46+
}
47+
}
48+
2249
log.Debug("Obtaining IDbConnection from Driver");
2350
try
2451
{
@@ -38,5 +65,44 @@ public override bool IsStatementCache
3865
get { return false; }
3966
}
4067

68+
public override void Close()
69+
{
70+
log.Info("cleaning up connection pool");
71+
72+
for(int i = 0; i < pool.Count; i++)
73+
{
74+
try
75+
{
76+
((IDbConnection)pool[i]).Close();
77+
}
78+
catch(Exception e)
79+
{
80+
log.Warn("problem closing pooled connection", e);
81+
}
82+
}
83+
84+
pool.Clear();
85+
}
86+
87+
public override void CloseConnection(IDbConnection conn)
88+
{
89+
if(log.IsDebugEnabled) checkedOut--;
90+
91+
lock(poolLock)
92+
{
93+
int currentSize = pool.Count;
94+
if( currentSize < PoolSize )
95+
{
96+
if(log.IsDebugEnabled) log.Debug("returning connection to pool, pool size: " + (currentSize + 1) );
97+
pool.Add(conn);
98+
return;
99+
}
100+
}
101+
102+
base.CloseConnection(conn);
103+
}
104+
105+
106+
41107
}
42108
}

src/NHibernate/Connection/IConnectionProvider.cs

+5
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,10 @@ public interface IConnectionProvider
5050
/// </remarks>
5151
bool IsStatementCache { get; }
5252

53+
/// <summary>
54+
/// Release all resources held by this ConnectionProvider.
55+
/// </summary>
56+
void Close();
57+
5358
}
5459
}

src/NHibernate/Connection/UserSuppliedConnectionProvider.cs

+7
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,12 @@ public override bool IsStatementCache
4747
get { return false; }
4848
}
4949

50+
public override void Close()
51+
{
52+
// do nothing - don't need to throw an error because this is something
53+
// that NHibernate will call.
54+
}
55+
56+
5057
}
5158
}

0 commit comments

Comments
 (0)