[英]Timeout error in ADO.NET with connection pooling
我們有舊版 SOAP ASP.NET 網絡服務,它連接到 SQL 服務器數據庫以檢索結果集。 下面是我們的連接字符串:
connectionString="server=ServerName;database=UserDBName;user id=UserNameRef;Password=myPassword;
我們將命令超時設置為 5 分鍾。 我們看到的是,我們的帶有連接池的 SQL Server 2012 數據庫經常發生超時問題錯誤。 服務器中沒有正在進行的主要活動或發生阻止問題。
來自sp_whoisactive
跟蹤的 PFB 快照。 如果我們看到,session 52 在 5 分鍾后超時。 我們沒有在這個 session 中運行任何命令。不知道,為什么它突然超時。
如何修復這些超時錯誤?
+---------+------------+-----------+----------+---------------------------+-------------+---------------------+-------------+------------+------------+-----------------+
| status | session_id | wait_info | sql_text | sql_command | login_name | blocking_session_id | host_name | start_time | login_time | collection_time |
+---------+------------+-----------+----------+---------------------------+-------------+---------------------+-------------+------------+------------+-----------------+
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:00 AM | 2:39:00 AM | 2:39:00 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:06 AM | 2:39:00 AM | 2:39:16 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:39:31 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:39:46 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:40:01 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:40:16 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:40:31 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:40:46 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:41:01 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:41:16 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:41:31 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:41:46 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:42:01 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:42:16 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:42:31 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:42:46 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:43:01 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:43:16 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:43:30 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:43:46 AM |
| dormant | 52 | NULL | | sys.sp_reset_connection;1 | UserNameRef | NULL | HostNameRef | 2:39:21 AM | 2:39:00 AM | 2:44:01 AM | <== Post this timeout occurs
+---------+------------+-----------+----------+---------------------------+-------------+---------------------+-------------+------------+------------+-----------------+
這聞起來像是尚未處理的資源。 我可以問你“你是在操作執行后立即處理連接和命令嗎?”:我推薦一個using
塊,它保證在塊末尾處理,如下所示:
string sqlConnectionString = "...(put the connection string here)..."; string commandText = "...(put the SQL command here)..."; using (var connection = new SqlConnection(sqlConnectionString)) { using (var command = new SqlCommand(commandText, connection)) { return command.ExecuteNonQuery(); } }
另一個問題可能與連接池算法有關,該算法表明,要從池中受益,連接字符串值非常重要:
只能合並具有相同配置的連接。 ADO.NET 同時保留幾個池,每個配置一個。 連接按連接字符串分隔到池中,在使用集成安全性時按 Windows 身份分隔。 連接也根據它們是否在事務中登記而被合並。
我知道您可能已經閱讀過它,但這是文檔的鏈接: SQL 服務器連接池 (ADO.NET)
請告訴我進展如何!
(按要求移至第一個答案的末尾)
問題中的跟蹤與超時問題無關。 很抱歉造成的混亂。 超時問題是由於阻塞問題而發生的,其中此 ASP.NET 網絡服務正在等待另一個長時間運行的 SQL 代理作業完成。
由於命令超時設置為 5 分鍾,SQL 代理作業正在寫入后台表並阻止此 ASP.NET web 服務調用。 被阻塞 5 分鍾后,由於命令超時 5 分鍾,ASP.NET 網絡服務超時。
應用的修復:
我們在分析了長時間運行的瓶頸后台作業的執行計划后修復了這個超時問題,通過將現有的非聚集索引更改為兩個后台表上的聚集索引,從而導致更快的數據檢索和更少的阻塞發生。 現在,超時問題消失了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.