253 lines
8.6 KiB
C#
253 lines
8.6 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Web;
|
|||
|
|
using CYQ.Data.Tool;
|
|||
|
|
|
|||
|
|
namespace CYQ.Data
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
internal partial class ConnObject
|
|||
|
|
{
|
|||
|
|
public ConnBean Master;
|
|||
|
|
public ConnBean BackUp;
|
|||
|
|
public MList<ConnBean> Slave = new MList<ConnBean>();
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>á<EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
internal void InterChange()
|
|||
|
|
{
|
|||
|
|
if (BackUp != null)
|
|||
|
|
{
|
|||
|
|
ConnBean middle = Master;
|
|||
|
|
Master = BackUp;
|
|||
|
|
BackUp = middle;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
static int index = -1;
|
|||
|
|
static readonly object o = new object();
|
|||
|
|
public ConnBean GetSlave()
|
|||
|
|
{
|
|||
|
|
if (Slave.Count > 0)
|
|||
|
|
{
|
|||
|
|
lock (o)
|
|||
|
|
{
|
|||
|
|
if (index == -1)
|
|||
|
|
{
|
|||
|
|
index = new Random().Next(Slave.Count);
|
|||
|
|
}
|
|||
|
|
if (index >= Slave.Count)//2
|
|||
|
|
{
|
|||
|
|
index = 0;
|
|||
|
|
}
|
|||
|
|
ConnBean slaveBean = Slave[index];
|
|||
|
|
index++;
|
|||
|
|
if (slaveBean.IsOK)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ء<F2B7B5BB>
|
|||
|
|
{
|
|||
|
|
return slaveBean;
|
|||
|
|
}
|
|||
|
|
else if (Slave.Count > 1)
|
|||
|
|
{
|
|||
|
|
//int i = index + 1;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD>¸<EFBFBD><C2B8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
for (int i = index + 1; i < Slave.Count + 1; i++)
|
|||
|
|
{
|
|||
|
|
if (i == Slave.Count)
|
|||
|
|
{
|
|||
|
|
i = 0;
|
|||
|
|
}
|
|||
|
|
if (i == index) { break; }
|
|||
|
|
if (Slave[i].IsOK)
|
|||
|
|
{
|
|||
|
|
return Slave[i];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//<2F><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (Master != null && Master.IsOK)
|
|||
|
|
{
|
|||
|
|
return Master;
|
|||
|
|
}
|
|||
|
|
else if (BackUp != null && BackUp.IsOK)
|
|||
|
|
{
|
|||
|
|
return BackUp;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣨Ĭ<E2A3A8><C4AC>10<31>룩
|
|||
|
|
/// </summary>
|
|||
|
|
public void SetFocusOnMaster()
|
|||
|
|
{
|
|||
|
|
if (Slave.Count > 0)
|
|||
|
|
{
|
|||
|
|
string id = StaticTool.GetMasterSlaveKey();//<2F><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>ı<EFBFBD>ʶ
|
|||
|
|
Cache.DistributedCache.Local.Set(id, 1, AppConfig.DB.MasterSlaveTime / 60.0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public bool IsAllowSlave()
|
|||
|
|
{
|
|||
|
|
if (Slave.Count == 0) { return false; }
|
|||
|
|
string id = StaticTool.GetMasterSlaveKey();//<2F><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>ı<EFBFBD>ʶ
|
|||
|
|
return !Cache.DistributedCache.Local.Contains(id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal partial class ConnObject
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵĶ<D3B5><C4B6><EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
private static MDictionary<string, ConnObject> connDicCache = new MDictionary<string, ConnObject>(StringComparer.OrdinalIgnoreCase);
|
|||
|
|
|
|||
|
|
internal static ConnObject Create(string connNameOrString)
|
|||
|
|
{
|
|||
|
|
connNameOrString = string.IsNullOrEmpty(connNameOrString) ? AppConfig.DB.DefaultConn : connNameOrString;
|
|||
|
|
if (connNameOrString.EndsWith("_Bak"))
|
|||
|
|
{
|
|||
|
|
connNameOrString = connNameOrString.Replace("_Bak", "");
|
|||
|
|
}
|
|||
|
|
if (connDicCache.ContainsKey(connNameOrString))
|
|||
|
|
{
|
|||
|
|
return connDicCache[connNameOrString];
|
|||
|
|
}
|
|||
|
|
ConnBean cbMaster = ConnBean.Create(connNameOrString);
|
|||
|
|
if (cbMaster == null)
|
|||
|
|
{
|
|||
|
|
#region <EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD>ȡĬ<EFBFBD><EFBFBD>Conn<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
string errMsg = string.Format("Can't find the connection key '{0}' from connectionStrings config section !", connNameOrString);
|
|||
|
|
if (connNameOrString == AppConfig.DB.DefaultConn)
|
|||
|
|
{
|
|||
|
|
Error.Throw(errMsg);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
ConnBean cb = ConnBean.Create(AppConfig.DB.DefaultConn); // <20><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>ConnName<6D><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>
|
|||
|
|
if (cb != null)
|
|||
|
|
{
|
|||
|
|
cbMaster = cb.Clone();//<2F><>ȡĬ<C8A1>ϵ<EFBFBD>ֵ<EFBFBD><D6B5>
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Error.Throw(errMsg);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
ConnObject co = new ConnObject();
|
|||
|
|
co.Master = cbMaster;
|
|||
|
|
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӱ<EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|||
|
|
if (connNameOrString != null && connNameOrString.Length < 32 && !connNameOrString.Trim().Contains(" ")) // ΪconfigKey
|
|||
|
|
{
|
|||
|
|
ConnBean coBak = ConnBean.Create(connNameOrString + "_Bak");
|
|||
|
|
if (coBak != null && coBak.ConnDataBaseType == cbMaster.ConnDataBaseType)
|
|||
|
|
{
|
|||
|
|
co.BackUp = coBak;
|
|||
|
|
co.BackUp.IsBackup = true;
|
|||
|
|
}
|
|||
|
|
for (int i = 1; i < 10000; i++)
|
|||
|
|
{
|
|||
|
|
ConnBean cbSlave = ConnBean.Create(connNameOrString + "_Slave" + i);
|
|||
|
|
if (cbSlave == null)
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
cbSlave.IsSlave = true;
|
|||
|
|
co.Slave.Add(cbSlave);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
if (!connDicCache.ContainsKey(connNameOrString) && co.Master.ConnName == connNameOrString) // <20><>һ<EFBFBD>µģ<C2B5><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD>ٻ<EFBFBD><D9BB><EFBFBD>
|
|||
|
|
{
|
|||
|
|
connDicCache.Set(connNameOrString, co);
|
|||
|
|
}
|
|||
|
|
return co;
|
|||
|
|
}
|
|||
|
|
public void SaveToCache(string key)
|
|||
|
|
{
|
|||
|
|
if (!connDicCache.ContainsKey(key))
|
|||
|
|
{
|
|||
|
|
connDicCache.Add(key, this);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public static void Clear()
|
|||
|
|
{
|
|||
|
|
connDicCache.Clear();
|
|||
|
|
}
|
|||
|
|
public static void Remove(string key)
|
|||
|
|
{
|
|||
|
|
connDicCache.Remove(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
internal partial class ConnObject
|
|||
|
|
{
|
|||
|
|
static ConnObject()
|
|||
|
|
{
|
|||
|
|
ThreadBreak.AddGlobalThread(new ParameterizedThreadStart(CheckConnIsOk));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵļ<D3B5><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ָ<EFBFBD><D6B8><EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="threadID"></param>
|
|||
|
|
public static void CheckConnIsOk(object threadID)
|
|||
|
|
{
|
|||
|
|
System.Diagnostics.Debug.WriteLine("ConnObject.CheckConnIsOk on Thread :" + threadID);
|
|||
|
|
while (true)
|
|||
|
|
{
|
|||
|
|
Thread.Sleep(1000);
|
|||
|
|
if (connDicCache.Count > 0)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
string[] items = new string[connDicCache.Count];
|
|||
|
|
connDicCache.Keys.CopyTo(items, 0);
|
|||
|
|
foreach (string key in items)
|
|||
|
|
{
|
|||
|
|
ConnObject obj = connDicCache[key];
|
|||
|
|
if (obj != null)
|
|||
|
|
{
|
|||
|
|
if (!obj.Master.IsOK)
|
|||
|
|
{
|
|||
|
|
if (obj.Master.ConnName == obj.Master.ConnString)
|
|||
|
|
{
|
|||
|
|
connDicCache.Remove(key);//<2F>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
obj.Master.TryTestConn();
|
|||
|
|
}
|
|||
|
|
if (obj.BackUp != null && !obj.BackUp.IsOK) { obj.BackUp.TryTestConn(); }
|
|||
|
|
if (obj.Slave != null && obj.Slave.Count > 0)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < obj.Slave.Count; i++)
|
|||
|
|
{
|
|||
|
|
if (!obj.Slave[i].IsOK)
|
|||
|
|
{
|
|||
|
|
obj.Slave[i].TryTestConn();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
items = null;
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|