1. 程式人生 > >解決C# WinForm程式與Oracle連線介面長時間沒有響應的問題

解決C# WinForm程式與Oracle連線介面長時間沒有響應的問題

程式情況:
C#編寫的WinForm程式(使用者管理系統),後端WCF服務為其提供資料,與Oracle相關的操作在WCF伺服器完成。
遇到問題:最近有使用者報告異常,描述WinForm的某個搜尋介面(去呼叫WCF服務在Oracle中查詢資料)一直處於等待狀態。DBA那邊也有人報告,一些呼叫該使用者管理系統相關的儲存過程的oracle session,一直處於執行狀態3個小時,對oracle資料庫造成了影響,需要手動結束掉這些程序。


最終找到的原因:
Oracle資料庫的表中突然的插入了大批量的資料,導致查詢變慢。然後使用者在WinForm介面檢索的時候,點選了搜尋按鈕,此時會呼叫WCF服務去檢索資料庫,但是檢索很慢,使用者在等待了3分鐘後不想再等待,便直接關掉了介面。注意這個過程中,WinForm在與WCF的連線中,雖然強迫關閉了客戶端,但是WCF的服務端程式碼執行到了一半,正在等待Oracle的返回結果,WCF端並沒有關閉,還是在一直執行的狀態,與Oracle的connection一直是連線狀態。


先說一說Oracle吧,如果C#呼叫其一個儲存過程,會建立一個connection,或者說session,Oracle有自動清理inactive session的機制,雖然不是實時的,但是有這個機制。如果C#與Oracle的session是持續的,那麼這個session就不會被清理掉。如果說C#呼叫了一個耗時的儲存過程,但是半途中C#退出了,那麼這個session就會變成inactive session,就會在合適的時候被Oracle清理掉。


現在這個問題是,使用者在Winform介面退出了,但是在WCF中還是在執行著,所以WCF伺服器與Oracle的連線一直是active session,所以儲存過程在執行了3個小時,還在執行。而且這時候,使用者又打開了新的WinForm介面,再次嘗試查詢,WCF又會開啟新的與Oracle session, 直到conncetion pool中可用的被用完(或者是Oracle伺服器最多能同時接受的連線達到最大值),WCF服務端與Oracle會話就會處於等待可用連線的狀態,然後WinForm介面自然就處於等待沒有響應的狀態。


解決辦法:
給WCF在連線Oracle的程式碼中增加timeout屬性,當執行超過5分鐘的時候,自動斷掉連線,之後Oracle中的inactive session就會被清除,而且C# WCF服務端的connection pool也會夠用,不會再出現等待狀態。


資料庫中儲存過程與查詢慢的原因:
這個表的資料量很大,而且剛剛有大批量的資料進來。Oracle有時候遇到這個問題,同樣的查詢語句,上一次執行的很慢,下一次可能很快就完成(這個DBA範疇的東西,我也不是太懂)。如果一個語句佔用這個表3個小時了,那麼別人session執行查詢語句也很慢(或許別人的session運氣好本來應該很快才對)。現在用timeout結束掉這個session,其他的session執行查詢語句,可能就快了。




https://stackoverflow.com/questions/12660636/oraclecommand-timeout?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa  comand tiem out

https://forums.devart.com/viewtopic.php?t=25872