該應用程序本身在我以前的question中描述。在DAL方面我用ODP .NET行爲怪異
Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342
這裏是連接字符串:
User id=usr;Password=pwd;Data Source=database1;Validate connection=True;Connection timeout=8;Pooling=false
的starange是,有時ODP引發了以下異常:
Oracle.ManagedDataAccess.Client.OracleException (0xFFFFFC18): Connection request timed out
in OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, String instanceName)
in OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
in OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
in OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword)
in Oracle.ManagedDataAccess.Client.OracleConnection.Open()
in MySyncApp.DBRepository.GetChangedDataDB(DateTime startPeriod) in D:\MySyncApp\MySyncApp\DB.cs:line 23
in MySyncApp.Program.<>c__DisplayClass30.<>c__DisplayClass32.<Synchronize>b__2f(ID id) in D:\MySyncApp\MySyncApp\Program.cs:line 441
但這個異常後,當我看看甲骨文的會議,我看到實際上連接是活着的和剛剛標記爲INACTIVE
!因此,這樣的連接將繼續掛在服務器端,逐漸耗盡可用會話的數量。
沒有什麼特別在我的代碼,只是
public List<DataObj> GetChangedDataDB(DateTime startPeriod)
{
List<DataObj> list = new List<DataObj>();
using (OracleConnection conn = new OracleConnection(this._connstr))
{
conn.Open();
using (OracleCommand comm = new OracleCommand("select data from table(usr.syncpackage.GetChanged(:pStart))", conn))
{
comm.CommandTimeout = 10;
comm.Parameters.Add(":pStart", startPeriod);
using (OracleDataReader reader = comm.ExecuteReader())
{
// ..omitted
}
}
}
return list;
}
這段代碼在Parallel.ForEach
循環運行從大量的數據庫,同時拉出數據。甚至可能是三個並行連接到同一個數據庫(從不同部門的企業中抽取出模式的不同部分的數據)。
的Oracle是
Oracle數據庫11g企業版發行11.2.0.3.0 - 64位 生產
同步過程本身觸發上在10秒的時間間隔定時器。如果已經捉迷藏任務,然後下一個任務正在停止:
public static void Synchronize(object obj)
{
// ... omitted
log.Info("ITERATION_COMMON_START");
if (Program.State == "Running")
{
log.Info("ITERATION_COMMON_END_BY_EXISTING");
return;
}
lock (Program.StateLock)
{
Program.State = "Running";
}
Parallel.ForEach(Global.config.dbs, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (l) =>
{
Console.WriteLine("Started synchronization for {0}", l.key);
DBRepository db = new DBRepository(l.connectionString);
Parallel.ForEach(l.departments, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (department) =>
{
DateTime ChangesFromTS = GetPreviousIterationTS;
List<DataObj> cdata = db.GetChangedDataDB(ChangesFromTS);
// ... doing the work here
}
}
// Finishing work
GC.Collect();
lock (Program.StateLock)
{
Program.State = "";
}
}
這裏是定時器定期調用同步任務:
Program.getModifiedDataTimer = new Timer(Program.Synchronize, null, (int)Global.config.syncModifiedInterval * 1000, (int)Global.config.syncModifiedInterval * 1000);
Global.config.syncModifiedInterval
以秒爲單位
ODP行爲本身以同樣的方式當我打開池。它創建的連接數超過了Max pool size
指令在連接字符串中允許的相同例外情況。
請告訴我你對這些東西的想法和經驗。
UPDATE
這裏是一塊Oracle跟蹤時引發異常:
(PUB) (ERR) OracleConnection.Open() (txnid=n/a) Oracle.ManagedDataAccess.Client.OracleException (0xFFFFFC18): Connection request timed out
in OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, String instanceName)
in OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
in OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
in OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword)
in Oracle.ManagedDataAccess.Client.OracleConnection.Open()
更新#2
好像這個連接顯示up b由於滯後連接,如請求建立oracle連接被髮送,但其響應被忽略。或者傳輸到/從服務器傳輸的數據在傳輸到目的地時被破壞。
即使關閉應用程序,連接仍然掛在服務器的會話列表中。當我殺死一個會議時,它會一直掛在列表上,並帶有「KILLED」標籤。
更新#3
Here爲演示應用程序,使得同樣的問題。正如我之前所說的那樣,它出現在糟糕的連接上,您可以使用WANem仿真器來模擬這種連接。 Here是我用於數據庫連接的相同組件。希望你的幫助。
您可以在應用程序發生變化時提供轉儲嗎? – Olivier
@Olivier請參閱我的第三個問題更新。希望它能讓你更容易地重現問題。但是,當然,我可以做個轉儲。 – kseen
你能解決嗎? –