|
@@ -10,12 +10,15 @@ namespace UAS_MES_NEW.DataOperate
|
|
|
class DataHelper
|
|
class DataHelper
|
|
|
{
|
|
{
|
|
|
//系统默认的的连接字符串
|
|
//系统默认的的连接字符串
|
|
|
- private string ConnectionStrings = "Connection Timeout=0;Pooling=false;Password=select!#%*(;User ID=YD_CYZZ;Pooling=false;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.85)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));";
|
|
|
|
|
|
|
+ private string ConnectionStrings = "Connection Timeout=30;Pooling=true;Min Pool Size=2;Max Pool Size=8;Connection Lifetime=300;Password=select!#%*(;User ID=YD_CYZZ;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.85)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));";
|
|
|
//用户选择的数据库的连接字符串
|
|
//用户选择的数据库的连接字符串
|
|
|
public static string DBConnectionString;
|
|
public static string DBConnectionString;
|
|
|
public static OracleConnection connection = null;
|
|
public static OracleConnection connection = null;
|
|
|
OracleCommand command = null;
|
|
OracleCommand command = null;
|
|
|
int ReconnectTime = 0;
|
|
int ReconnectTime = 0;
|
|
|
|
|
+ //记录当前 static connection 使用的连接串,用于检测账套切换
|
|
|
|
|
+ private static string currentConnString = null;
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 执行构造函数的时候打开数据库的链接
|
|
/// 执行构造函数的时候打开数据库的链接
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -24,11 +27,28 @@ namespace UAS_MES_NEW.DataOperate
|
|
|
try
|
|
try
|
|
|
{
|
|
{
|
|
|
//如果选择的是默认数据则直接用配置文件的信息连接,否则选择数据库的账套信息
|
|
//如果选择的是默认数据则直接用配置文件的信息连接,否则选择数据库的账套信息
|
|
|
|
|
+ string targetConnString;
|
|
|
if (DBConnectionString == null || DBConnectionString == ConnectionStrings)
|
|
if (DBConnectionString == null || DBConnectionString == ConnectionStrings)
|
|
|
- connection = new OracleConnection(ConnectionStrings);
|
|
|
|
|
|
|
+ targetConnString = ConnectionStrings;
|
|
|
else
|
|
else
|
|
|
- connection = new OracleConnection(DBConnectionString);
|
|
|
|
|
- connection.Open();
|
|
|
|
|
|
|
+ targetConnString = DBConnectionString;
|
|
|
|
|
+
|
|
|
|
|
+ //连接复用:仅当连接不存在/未打开/账套切换时才重建。
|
|
|
|
|
+ //原实现每次 new DataHelper() 都覆盖 static connection 新建物理连接,
|
|
|
|
|
+ //旧连接因窗体 dh 实例持有引用不被 GC,导致单客户端泄漏 20+ 个数据库会话。
|
|
|
|
|
+ if (connection == null || connection.State != ConnectionState.Open || currentConnString != targetConnString)
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (connection != null)
|
|
|
|
|
+ connection.Close(); //开启连接池后 Close 归还池,不再占用数据库会话
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception) { }
|
|
|
|
|
+
|
|
|
|
|
+ connection = new OracleConnection(targetConnString);
|
|
|
|
|
+ connection.Open();
|
|
|
|
|
+ currentConnString = targetConnString;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
catch (Exception e) { LogManager.DoLog(e.Message); }
|
|
catch (Exception e) { LogManager.DoLog(e.Message); }
|
|
|
}
|
|
}
|
|
@@ -307,6 +327,36 @@ namespace UAS_MES_NEW.DataOperate
|
|
|
return dt;
|
|
return dt;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 通过表名,字段获取DataTable类型的数据(带行数上限,防止全表加载导致内存膨胀)
|
|
|
|
|
+ /// 列表类界面应优先使用此重载或已有的 getFieldsDatasByPageing,避免无限制 Fill 全表
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ public DataTable getFieldsDatas(string TableName, string Fields, int maxRows)
|
|
|
|
|
+ {
|
|
|
|
|
+ DataTable dt = new DataTable();
|
|
|
|
|
+ string sql = "select " + Fields + " from " + TableName + " where rownum <= " + maxRows;
|
|
|
|
|
+ command = new OracleCommand(sql, connection);
|
|
|
|
|
+ Reconnect(command);
|
|
|
|
|
+ OracleDataAdapter ad = new OracleDataAdapter();
|
|
|
|
|
+ ad.SelectCommand = command;
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ ad.Fill(dt);
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception)
|
|
|
|
|
+ {
|
|
|
|
|
+ connection = new OracleConnection(DBConnectionString);
|
|
|
|
|
+ connection.Open();
|
|
|
|
|
+ command = new OracleCommand(sql, connection);
|
|
|
|
|
+ ad = new OracleDataAdapter();
|
|
|
|
|
+ ad.SelectCommand = command;
|
|
|
|
|
+ ad.Fill(dt);
|
|
|
|
|
+ }
|
|
|
|
|
+ ad.Dispose();
|
|
|
|
|
+
|
|
|
|
|
+ return dt;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 根据DataTable和指定的表名更新数据,如果需要保存新增的数据则需要传递一条Insert的SQL
|
|
/// 根据DataTable和指定的表名更新数据,如果需要保存新增的数据则需要传递一条Insert的SQL
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -1147,15 +1197,41 @@ namespace UAS_MES_NEW.DataOperate
|
|
|
|
|
|
|
|
public void Dispose()
|
|
public void Dispose()
|
|
|
{
|
|
{
|
|
|
-
|
|
|
|
|
|
|
+ //command 为实例字段,可安全释放
|
|
|
|
|
+ if (command != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ try { command.Dispose(); } catch (Exception) { }
|
|
|
|
|
+ command = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ //connection 为 static 共享对象,开启连接池后由连接池统一管理生命周期,
|
|
|
|
|
+ //此处不主动 Close 以避免影响其它正在使用该连接的实例
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void Reconnect(OracleCommand cmd)
|
|
private void Reconnect(OracleCommand cmd)
|
|
|
{
|
|
{
|
|
|
- if (cmd.Connection.State == ConnectionState.Closed)
|
|
|
|
|
|
|
+ //先确保连接对象存在,避免null引用
|
|
|
|
|
+ if (cmd.Connection == null)
|
|
|
{
|
|
{
|
|
|
- cmd.Connection.Open();
|
|
|
|
|
- LogManager.DoLog("超时重连");
|
|
|
|
|
|
|
+ cmd.Connection = new OracleConnection(string.IsNullOrEmpty(DBConnectionString) ? ConnectionStrings : DBConnectionString);
|
|
|
|
|
+ }
|
|
|
|
|
+ ConnectionState state = cmd.Connection.State;
|
|
|
|
|
+ //Closed/Broken 才需要重连,正常状态直接返回,减少无谓的异常触发
|
|
|
|
|
+ if (state == ConnectionState.Closed || state == ConnectionState.Broken)
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (state == ConnectionState.Broken)
|
|
|
|
|
+ {
|
|
|
|
|
+ cmd.Connection.Close();
|
|
|
|
|
+ }
|
|
|
|
|
+ cmd.Connection.Open();
|
|
|
|
|
+ LogManager.DoLog("连接状态异常(" + state + ")已重连");
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ LogManager.DoLog("重连失败:" + ex.Message);
|
|
|
|
|
+ throw;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|