2017年2月19日 星期日

[Entity Framework]provider: Session Provider, error 19 - 實體連接不可用

最近利用ASP.NET MVC5搭配Entity Framework寫了一個小功能,監控資料表數量!
該程式每30秒會採polling的方式向SQL Server詢問目前資料表中的資料數量,並顯示在網站頁面中。

經同事報案,在執行過程中不定時會發生Exception,錯誤描述如下:
在接收來自伺服器的要求時發生傳輸層級的錯誤。 
(provider: Session Provider, error 19 - 實體連接不可用)

以下是該功能的樣貌:
前端JavaScript
/**
 * 取得目前資料表資料數量
 */
function callAjaxGetCount() {
    $.ajax({
        url: 'http://localhost/Count/GetCount',
        type: 'POST',
        dataType: 'json',
        success: function (response) {
            //do something when success. 
        }
        setTimeout(function () { callAjaxGetCount() }, 30000);
    });
}
Controller
public class CountController : Controller
{
    #region 變數
    CountBo countBo;
    #endregion

    #region Constructor
    public CountController()
    {
        countBo = new CountBo();
    }
    #endregion

    [HttpPost]
    public string GetCount()
    {
        return countBo.GetDBTableCount().ToString();
    }
}
Model-BusinessObject
public class CountBo
{
    #region 變數
    HowardDB _db;
    #endregion

    #region Constructor
    public CountBo()
    {
     _db = new HowardDB();
    }
    #endregion

    #region Destructor
    ~CountBo()
    {
        _db.Dispose();
    }
    #endregion

    /// <summary>
    /// 取得資料表資料數量
    /// </summary>
    public int GetDBTableCount()
    {
        return _db.Set<Table>().Count();
    }
}

哇哩咧,最討厭那種「不一定」會出現的問題了!
爬文後整理可能會出現這樣錯誤的原因如下:
1. 這只是暫行性的錯誤?!
2. 網路瞬斷!
3. 客戶端與資料庫連線問題,網路線?交換器?
4. SQL Server意外重啟,可查看Event log
5. SQL Server效能不佳...
6. C#取用資料庫後未關閉連線,導致連線數量過多
7. Entity Framework從pool中取得共用連線字串卻已被SQL Server自動中斷連線

開發用的SQL Server一直都是穩定狀態(雖然最近一直發現效能逐漸下滑...),共同開發的其他夥伴也都未發生這樣的情形。
目前暫定處裡的方法是將呼叫ajax方法確定結束後才再次執行SetTimeout,嘗試做SqlConnection.ClearAllPools();清除連線暫存。
前端JavaScript
/**
 * 取得目前資料表資料數量
 */
function callAjaxGetCount() {
    $.ajax({
        url: 'http://localhost/Count/GetCount',
        type: 'POST',
        dataType: 'json',
        success: function (response) {
     //do something when success. 
        },
        complete: function(){
            setTimeout(function () { callAjaxGetCount() }, 30000);
        }
    });
}
Model-BusinessObject
/// <summary>
/// 取得資料表資料數量
/// </summary>
public int GetDBTableCount()
{
    SqlConnection.ClearAllPools();
    return _db.Set<Table>().Count();
}

目前整體運行看來還行,持續觀察囉...

參考資料:
A transport-level error has occurred when receiving results from the server
Unstable connection? 'Physical connection is not usable
A transport-level error has occurred when sending the request to the server.
SOLUTION FOR: A TRANSPORT-LEVEL ERROR HAS OCCURRED WHEN RECEIVING RESULTS FROM THE SERVER…

沒有留言:

張貼留言