随分前に、自社で勤怠管理システムを開発し導入しました。しかし、導入したサーバマシンがうるさいとの理由でサーバを変更し、ついでに OS や データベースのバージョンアップを行うことになりました。
スポンサーリンク
私が開発したわけではなかったこともあり担当になりませんでしたが、SQL Server 2003 から SQL Server 2008R2 へ変更し、IIS や OS もアップデートしたようです。 開発言語は、ASP.NET ( VB ) でした。ところが、数回操作すると以下のエラーが発生するようになったとのことでヘルプを求められましたので、デバッグ作業開始です。実は、以下のエラーは最終的な調査結果でありまして、この段階では「数回操作するとデータベースに接続できなくなる」と言うことまでがわかっていた状況です。
エラー内容
タイムアウトに達しました。プールから接続を取得する前にタイムアウト期間が過ぎました。
プールされた接続がすべて使用中で、プールサイズの制限値に達した可能性があります。
原因
調べていくと、接続を閉じていない場合に発生するエラーと言うことまではわかりました。特に接続部分を中心にソースコードを追っていくと、以下のようなコードでした。重要でない部分は編集(主に削除)してありますが、実際の状況は悲惨でした。惨状であり、怒りよりも悲しい気持ちになりました。
Public Class ClsSql Protected con1 As SqlConnection Protected sql1 As String Public Sub New() sql1 = "" Try con1 = CreateConn() con1.Open() ' DBに接続 Catch ex As Exception End Try End Sub Public Sub SqlReader(ByVal sql As String) sql1 = sql Try con1 = CreateConn() con1.Open() ' DBに接続 Catch ex As Exception End Try End Sub ' ' その他省略 ' End Class ' 参照系SQLは全て、以下のように使用している。 Dim r As ClsSql = Nothing r = New ClsSql() Call r.SqlReader(sql)
問題は、一目瞭然です。コンストラクタで接続して解放せずに、すぐさまメソッドでまた接続して・・・・・ 細かいことはぐっとこらえることにしましても、必ずデータベースに接続したら切断しましょうと言う話です。ただ、それだけです。
一応対策としては、コンストラクタ内の処理をすべてコメントアウトしただけでですが、見ての通りエラー内容も揉み消されているコードのため、特定までにはそれなりに時間がかかりました。しかし、なぜ今になってエラーが出るようになったんだしょうか。やはりバージョンアップをきっかけに、潜在的なバグが出現したのでしょうか。
参考