Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Đã có một DataReader mở ... mặc dù nó không phải là

Tôi nghi ngờ đây là sự cố, ở cuối phương pháp:

this.connectionPool.Putback(sqlConnection);

Bạn chỉ đang lấy hai phần tử từ trình lặp - vì vậy bạn không bao giờ hoàn thành while vòng lặp trừ khi thực sự chỉ có một giá trị được trả về từ trình đọc. Bây giờ bạn đang sử dụng LINQ, LINQ sẽ tự động gọi Dispose() trên trình lặp, vì vậy using tuyên bố sẽ vẫn loại bỏ trình đọc - nhưng bạn không đặt kết nối trở lại nhóm. Nếu bạn làm điều đó trong finally chặn, tôi nghĩ bạn sẽ ổn:

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);
}

Hoặc lý tưởng hơn, nếu nhóm kết nối của bạn là do bạn tự triển khai, hãy tạo Take trả về một cái gì đó triển khai IDisposable và trả kết nối trở lại nhóm khi hoàn tất.

Đây là một chương trình ngắn nhưng đầy đủ để chứng minh những gì đang diễn ra mà không có bất kỳ cơ sở dữ liệu thực tế nào liên quan:

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));
    }
}

Như đã viết - mô hình hóa tình huống với người đọc chỉ tìm thấy hai giá trị - kết quả đầu ra là:

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

Lưu ý rằng đầu đọc được xử lý, nhưng chúng tôi không bao giờ trả lại được bất cứ thứ gì từ hồ bơi. Nếu bạn thay đổi Main để mô hình hóa tình huống trong đó người đọc chỉ có một giá trị, như sau:

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

Sau đó, chúng tôi nhận được tất cả các cách thông qua while vòng lặp, vì vậy đầu ra thay đổi:

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

Tôi đề nghị bạn sao chép chương trình của tôi và thử nghiệm với nó. Đảm bảo rằng bạn hiểu mọi thứ về những gì đang diễn ra ... sau đó bạn có thể áp dụng nó cho mã của riêng mình. Bạn có thể muốn đọc bài viết của tôi về chi tiết triển khai khối trình lặp quá.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Giá trị BIGINT UNSIGNED nằm ngoài phạm vi

  2. Làm cách nào để lưu trữ 60 Boolean trong Cơ sở dữ liệu MySQL?

  3. Tìm kiếm MySQL bằng PHP và hiển thị kết quả trên cùng một trang

  4. Không thể cài đặt mysql-python (phiên bản mới hơn) trong Windows

  5. Cách tạo cơ sở dữ liệu với Liquibase