表面看起来,如果有多线程同时访问GetGateway方法,有可能会出现异样,因为方法中使用了静态参数MaxPool和ConnectionList,在GetGateway方法中加锁了,再抛异常放到lock外面去. /// <summary> /// 数据访问层代理实现类 /// </summary> public class ORMHelper { //连接池的最大值和最小值(默认为1) private const int MaxPool = 50; private static object o = new object() public static List<Connection> ConnectionList = new List<Connection>(MaxPool);
public static Gateway GetGateway(DbTransaction trans) { Gateway gateway = null; bool isMax = false; lock(o) { foreach (Connection conn in ConnectionList) { if (conn.Tran == trans) { gateway = conn.Conn; conn.CallTime = DateTime.Now; break; } } if (gateway == null) { if (ConnectionList.Count == MaxPool) isMax = true; gateway = CreateGateway(); ConnectionList.Add(new Connection(gateway, null, ConnectionList.Count.ToString())); } } if(isMax) throw new Exception("数据库连接池已满,请等待..."); return gateway; } } public static List<Connection> ConnectionList = new List<Connection>(MaxPool); 考虑改称字典,然后每个Connection都有自己的唯一key,也不需要foreach来判断了,直接用字典的方法查询是否存在key,会提高不少效率的.
/// <summary>
/// 数据访问层代理实现类
/// </summary>
public class ORMHelper
{
//连接池的最大值和最小值(默认为1)
private const int MaxPool = 50;
private static object o = new object()
public static List<Connection> ConnectionList = new List<Connection>(MaxPool);
public static Gateway GetGateway(DbTransaction trans)
{
Gateway gateway = null;
bool isMax = false;
lock(o)
{
foreach (Connection conn in ConnectionList)
{
if (conn.Tran == trans)
{
gateway = conn.Conn;
conn.CallTime = DateTime.Now;
break;
}
}
if (gateway == null)
{
if (ConnectionList.Count == MaxPool)
isMax = true;
gateway = CreateGateway();
ConnectionList.Add(new Connection(gateway, null, ConnectionList.Count.ToString()));
}
}
if(isMax) throw new Exception("数据库连接池已满,请等待...");
return gateway;
}
}
public static List<Connection> ConnectionList = new List<Connection>(MaxPool);
考虑改称字典,然后每个Connection都有自己的唯一key,也不需要foreach来判断了,直接用字典的方法查询是否存在key,会提高不少效率的.
if (ConnectionList.Count == MaxPool)
isMax = true;
else
{
gateway = CreateGateway();
ConnectionList.Add(new Connection(gateway, null, ConnectionList.Count.ToString()));
}
多谢你帮忙分析,只能先试试这种方式能不能行了,毕竟是低偶发性的发生类似情况,所以错误的排查很是艰难~~ 除了上述修改,不知道还有没有其他更好的建议?模拟数据还不简单,开几个线程,线程里面开while,疯狂的些数据~~
Connection 本身就有自己的线程池,你又操那心自己又建一个。。