簡體   English   中英

ServiceStack:檢測IDbConnection是否“忙” - DataReader是否已打開(嘗試實現“連接池”)

[英]ServiceStack: Detect if IDbConnection is “busy” - is a DataReader is open (trying to implement a “connection pool”)

我正在測試ServiceStacks OrmLite。 我已經普遍使用沒有OrmLite的MySql,現在我遇到了此錯誤消息中最簡單描述的問題:

已經有一個與此Connection關聯的開放DataReader,必須先關閉它。

由於我有一個多線程應用程序,某些線程將輪詢數據庫,而其他線程將在需要時插入,更新或選擇“按需”。 這導致上述異常。

我需要做的是能夠檢測連接(IDbHandler)是否“忙”; 有一個開放的DataReader或其他東西。 如果它正忙,請進行下一個連接(從我想要實現的“連接池”)。 問題是,我沒有可以在IDbHandler對象中使用的方法或屬性來確定它是否繁忙。

我已經在“正常”的mysql情況下通過簡單地使用我發送MySqlCommand或只是查詢字符串的方法解決了這個問題,例如:

dbConnections.ExecuteQuery("SELECT * FROM test");
dbConnections.ExecuteQuery(cmd); // cmd == MySqlCommand

並且ExecuteQuery將處理找到一個打開的連接,並在那里傳遞cmd /查詢。

但是,由於我使用OrmLite,它有很多IDbConnection的擴展方法,我不想為每個方法創建“代理方法”。 在上面簡單的mysql案例中,實際上只需要一個方法,它需要一個MySqlCommand,但OrmLite中的許多方法都不是這樣。

第一個問題:

  • 如何檢測連接是否繁忙? 我想避免嘗試捕獲情況來檢測它。

第二個問題:

  • 有沒有辦法傳遞整個“方法”調用,如:

例:

dbConnections.Run(iDbHandler.Select<MyObject>(q => q.Id > 10));
// or
dbConnections.Run(iDbHandler.Where<MyObject>(q => q.Id > 10));
// or
dbConnections.Run(iDbHandler.SomeOtherWeirdMetod<MyObject>(q => bla bla bla));

到目前為止,這不是最好的解決方案,但它是我正在測試的方法,以查看它如何處理我的特定情況(目前在版本3.97)。 和Ted一樣,我看到開放式數據讀取器經常例外,或者連接被關閉返回。

在我的使用中,所有服務都繼承我的父服務(后者繼承服務)來處理一些常見的元數據處理。 我選擇讓我的基本服務覆蓋服務的Db屬性,並快速檢查Db連接的狀態並嘗試恢復。 立即修復的一個案例如下:

我的MsSql服務器正在故障轉移群集中運行。 當SQL服務器從節點A翻轉到節點B時,我沒有在ServiceStack中找到內置機制來檢測其內存連接是否“臟”並需要重新連接。

歡迎提出意見和改進。

public override System.Data.IDbConnection Db
{
    get
    {
        try
        {
            var d = base.Db;
            if (d == null || d.State != System.Data.ConnectionState.Open)
                return  ForceNewDbConn();
            else
                return d;
        }
        catch (Exception ex)
        {
            return ForceNewDbConn();
            //throw;
        }
    }
}

private IDbConnection ForceNewDbConn()
{
    try
    {
        var f = TryResolve<IDbConnectionFactory>();
        if (f as OrmLiteConnectionFactory != null)
        {
            var fac = f as OrmLiteConnectionFactory;
            fac.AutoDisposeConnection = true;
            var newDBconn = fac.Open();
            return newDBconn;
        }
        return base.Db;
    }
    catch (Exception ex)
    {
        throw;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM