sql >> データベース >  >> RDS >> Mysql

すでに開いているDataReaderがあります...そうではありませんが

    メソッドの最後に、これが問題だと思います:

    this.connectionPool.Putback(sqlConnection);
    

    あなたは取っている イテレータからの2つの要素-したがって、whileを完了することはありません リーダーから返される値が実際に1つだけでない限り、ループします。現在、LINQを使用しています。LINQは自動的にDispose()を呼び出します。 イテレータで、using ステートメントは引き続きリーダーを破棄しますが、接続をプールに戻すことはありません。 finallyでそれを行う場合 ブロック、大丈夫だと思います:

    var sqlConnection = this.connectionPool.Take();
    try
    {
        // Other stuff here...
    
        using (var reader = this.selectWithSourceVectorCommand.ExecuteReader())
        {
            while (reader.Read())
            {
                yield return ReaderToVectorTransition(reader);
            }
        }
    }
    finally
    {
        this.connectionPool.Putback(sqlConnection);
    }
    

    または、理想的には、接続プールが独自の実装である場合は、Takeを作成します IDisposableを実装するものを返します 完了したら、接続をプールに戻します。

    これは、実際のデータベースを使用せずに、何が起こっているかを示すための短いが完全なプログラムです。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    class DummyReader : IDisposable
    {
        private readonly int limit;
        private int count = -1;
        public int Count { get { return count; } }
    
        public DummyReader(int limit)
        {
            this.limit = limit;
        }
    
        public bool Read()
        {
            count++;
            return count < limit;
        }
    
        public void Dispose()
        {
            Console.WriteLine("DummyReader.Dispose()");
        }
    }
    
    class Test
    {    
        static IEnumerable<int> FindValues(int valuesInReader)
        {
            Console.WriteLine("Take from the pool");
    
            using (var reader = new DummyReader(valuesInReader))
            {
                while (reader.Read())
                {
                    yield return reader.Count;
                }
            }
            Console.WriteLine("Put back in the pool");
        }
    
        static void Main()
        {
            var data = FindValues(2).Take(2).ToArray();
            Console.WriteLine(string.Join(",", data));
        }
    }
    

    書かれているように-読者が2つの値を見つけるだけで状況をモデル化する-出力は次のとおりです:

    Take from the pool
    DummyReader.Dispose()
    0,1
    

    リーダーは破棄されますが、プールから何かを返すことはできません。 Mainを変更した場合 次のように、リーダーの値が1つしかない状況をモデル化するには:

    var data = FindValues(1).Take(2).ToArray();
    

    次に、whileを最後まで実行します。 ループするため、出力が変化します:

    Take from the pool
    DummyReader.Dispose()
    Put back in the pool
    0
    

    私のプログラムをコピーして試してみることをお勧めします。何が起こっているかについてすべてを理解していることを確認してください...それからあなたはそれをあなた自身のコードに適用することができます。 イテレータブロックの実装の詳細 に関する私の記事を読むことをお勧めします。



    1. Mysqlはlikeとのベストマッチで選択します

    2. bash-変数へのSQLクエリ出力

    3. SQLSTATE [42000]:構文エラーまたはアクセス違反:1064

    4. Mysql1ランダム行