第一次使用.NET配合ORACLE進行任務操作,使用的數據驅動為:Oracle Data Provider for .NET, Managed Driver(Release 11.2.0.3.50 Beta)
問題的出現和其他人出現的場景一樣,在進行一次循環7萬次的流程中使用OracleCommand獲取數據時發生。
查詢了相關材料,
1.對ORACLE本身進行相應的CURSOR數量設置
SQL> alter system set open_cursors=3000 scope=both;
2.在程序內每次調用完相應的COMMAND後將其關閉(連同關閉連接)。但問題同樣發生。
具體代碼如下:
[csharp]
Parallel.ForEach(dtMainXM.AsEnumerable(), (pDataRowXMK) =>
{
DataTable dtDetail = new DataTable();<P> string ID=pDataRowXMK["ID"].ToString();
using (var pSConn = GetSourceConnection())
{
using (OracleCommand cmdSubXM = new OracleCommand())
{
cmdSubXM.Connection = pSConn;
cmdSubXM.CommandText = "select * from tableXX where ID='"+ ID +"'";
using (var iReader = cmdSubXM.ExecuteReader(CommandBehavior.CloseConnection))
{
dtDetail.Load(iReader);
}
}
}
}</P>
Parallel.ForEach(dtMainXM.AsEnumerable(), (pDataRowXMK) =>
{
DataTable dtDetail = new DataTable(); string ID=pDataRowXMK["ID"].ToString();
using (var pSConn = GetSourceConnection())
{
using (OracleCommand cmdSubXM = new OracleCommand())
{
cmdSubXM.Connection = pSConn;
cmdSubXM.CommandText = "select * from tableXX where ID='"+ ID +"'";
using (var iReader = cmdSubXM.ExecuteReader(CommandBehavior.CloseConnection))
{
dtDetail.Load(iReader);
}
}
}
}上述代碼中每個並行處理過程中,都對相應的資源進行了釋放,但問題還是出現(數據庫也設置成3000的CURSOR數量)。
最終通過嘗試,分析問題,對代碼進行修改,主要問題還是出在cmdSubXM.CommandText 為字符串拼接的原因。將代碼修改為參數模式後,無上述問題出現。
[csharp]
Parallel.ForEach(dtMainXM.AsEnumerable(), (pDataRowXMK) =>
{
DataTable dtDetail = new DataTable();
string ID=pDataRowXMK["ID"].ToString();
using (var pSConn = GetSourceConnection())
{
using (OracleCommand cmdSubXM = new OracleCommand())
{
cmdSubXM.Connection = pSConn;
cmdSubXM.CommandText = "select * from tableXX where ID=:ID";
//修改為參數方式
cmdSubXM.Parameters.Add("ID", ID);
using (var iReader = cmdSubXM.ExecuteReader(CommandBehavior.CloseConnection))
{
dtDetail.Load(iReader);
}
}
}
}
Parallel.ForEach(dtMainXM.AsEnumerable(), (pDataRowXMK) =>
{
DataTable dtDetail = new DataTable();
string ID=pDataRowXMK["ID"].ToString();
using (var pSConn = GetSourceConnection())
{
using (OracleCommand cmdSubXM = new OracleCommand())
{
cmdSubXM.Connection = pSConn;
cmdSubXM.CommandText = "select * from tableXX where ID=:ID";
//修改為參數方式
cmdSubXM.Parameters.Add("ID", ID);
using (var iReader = cmdSubXM.ExecuteReader(CommandBehavior.CloseConnection))
{
dtDetail.Load(iReader);
}
}
}
}
通過前後SQL語句的處理方式,個人理解還是ORACLE的SQL解析計劃引起的問題. 使用SQL參數,將最大程度的利用計劃緩存.而前一種方式,沒有重用性.