[英]OracleConnection Connection Request Timed out
在 a.Net Core 3.1 多線程控制台應用程序中出現問題; 如果對ThreadPool.QueueUserWorkItem的調用次數超過ThreadPool.SetMaxThreads中設置的線程數, OracleConnection將始終拋出“連接請求超時”異常。 “任務”是對 Oracle 中存儲過程的調用,該過程通過 cursor 返回數據。 在一個線程中一切正常,沒有問題
這是 in.Net Core 3.1 使用 Oracle.ManagedDataAccess.Client 的最新 nuget 版本
在 Oracle 連接字符串、池大小、連接生命周期連接超時等中嘗試了許多設置組合。似乎沒有任何幫助。 一旦排隊的任務數超過線程數,連接上的Open調用將引發異常。
使用 OracleConfiguration 進行跟蹤會發現異常:
2020-09-23 21:30:51.997780 TID:6 (PRI) (ERR) (CP) PoolManager.CreateNewPR() (txnid=n/a) Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out
at OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, OracleConnection connRefForCriteria, String instanceName, List`1 switchFailedInstNames)
一些線程留在以下 state “搜索空閑連接”:
2020-09-23 21:28:57.443815 TID:13 (PRI) (ENT) (CP) PoolManager.Get() MultiTenant : Searching for a idle connection, retryCountWithoutAffinity: 0
重現代碼:
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
using System;
using System.Data;
using System.Diagnostics;
using System.Threading;
namespace OracleDBStoredProc
{
class Program
{
private static Object lockObj = new Object();
static void Main(string[] args)
{
int numThreads = 10;
ThreadPool.SetMaxThreads(numThreads, numThreads);
for (int i = 0; i < numThreads+ 1; i++)
{
string myMsg = $" TASK {i} ";
ThreadPool.QueueUserWorkItem(CallToDatabase, myMsg);
Console.WriteLine(myMsg + " created.");
}
Console.WriteLine("Finished");
Console.ReadKey();
}
static void CallToDatabase(Object stateInfo)
{
OracleConfiguration.TraceOption = 1;
OracleConfiguration.TraceFileLocation = @"C:\traces";
OracleConfiguration.TraceLevel = 2;
string taskName = (string)stateInfo;
Console.WriteLine(taskName + "started");
string constr = "User Id=MyUser;Password=MyPswd;Data Source=(DESCRIPTION= (ADDRESS= (PROTOCOL=tcp)(HOST=MyServer)(PORT=1521))(CONNECT_DATA= (SERVICE_NAME=myservice)))";
OracleConnection con = new OracleConnection(constr);
con.Open();
var cmd = new OracleCommand("MY_APP.GET_MY_DATA", con)
{
CommandType = CommandType.StoredProcedure
};
OracleParameter p1 = cmd.Parameters.Add("refcur_ret", OracleDbType.RefCursor, ParameterDirection.Output);
p1.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
OracleDataReader reader1 = ((OracleRefCursor)p1.Value).GetDataReader();
DataTable test = new DataTable();
test.Load(reader1);
reader1.Close();
reader1.Dispose();
p1.Dispose();
cmd.Dispose();
con.Close();
con.Dispose();
String msg = null;
Thread thread = Thread.CurrentThread;
lock (lockObj)
{
msg = String.Format("{0} thread information\t", taskName) +
String.Format(" Thr ID: {0}\t\t", thread.ManagedThreadId);
}
Console.WriteLine(msg);
}
}
}
我遇到過同樣的問題。 使用線程而不是任務修復了它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.