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

Sự cố kết nối với SQLAlchemy và nhiều quy trình

Trích dẫn "Làm cách nào để sử dụng engine / kết nối / phiên với đa xử lý Python hoặc os.fork ()?" với sự nhấn mạnh thêm:

Đối tượng SQLAlchemy Engine đề cập đến một nhóm kết nối của các kết nối cơ sở dữ liệu hiện có. Vì vậy, khi đối tượng này được sao chép sang quy trình con, mục tiêu là đảm bảo rằng không có kết nối cơ sở dữ liệu nào được chuyển sang .

Tuy nhiên, đối với trường hợp Phiên hoặc Kết nối đang hoạt động giao dịch được chia sẻ, không có bản sửa lỗi tự động nào cho việc này; ứng dụng cần đảm bảo một quy trình con mới chỉ khởi tạo các đối tượng và giao dịch Kết nối mới, cũng như các đối tượng Phiên ORM.

Sự cố bắt nguồn từ quá trình con được chia nhỏ kế thừa session toàn cầu trực tiếp , đang giữ một Connection . Khi target cuộc gọi init , nó ghi đè các tham chiếu chung đến enginesession , do đó giảm số tiền hoàn lại của chúng xuống 0 ở trẻ, buộc chúng phải hoàn tất. Ví dụ:nếu bạn bằng cách này hay cách khác tạo một tham chiếu khác đến phiên kế thừa trong phần con, bạn sẽ ngăn nó bị xóa - nhưng đừng làm điều đó. Sau main đã tham gia và trở lại hoạt động kinh doanh như bình thường. Nó đang cố gắng sử dụng kết nối hiện có khả năng đã hoàn thiện - hoặc không đồng bộ - kết nối. Về lý do tại sao điều này gây ra lỗi chỉ sau một số lần lặp lại, tôi không chắc.

Cách duy nhất để xử lý tình huống này bằng cách sử dụng hình cầu theo cách bạn làm là

  1. Đóng tất cả các phiên
  2. Gọi engine.dispose()

trước khi rèn. Điều này sẽ ngăn không cho các kết nối bị rò rỉ sang đứa trẻ. Ví dụ:

def main():
    global session
    init()
    try:
        dummy = Dummy(value=1)
        session.add(dummy)
        session.commit()
        dummy_id = dummy.id
        # Return the Connection to the pool
        session.close()
        # Dispose of it!
        engine.dispose()
        # ...or call your cleanup() function, which does the same
        p = multiprocessing.Process(target=target, args=(dummy_id,))
        p.start()
        p.join()
        # Start a new session
        session = Session()
        dummy = session.query(Dummy).get(dummy_id)
        assert dummy.value == 2
    finally:
        cleanup()

Ví dụ thứ hai của bạn không kích hoạt quá trình hoàn thiện trong phần con và vì vậy nó chỉ có vẻ hoạt động, mặc dù nó có thể bị hỏng như ví dụ đầu tiên, vì nó vẫn đang kế thừa một bản sao của phiên và kết nối của nó được xác định cục bộ trong main .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LỖI:không thể truy cập tệp “$ libdir / plpython2” - LỖI:không thể truy cập tệp “$ libdir / plpython3”

  2. Nhận NoSuchMethodError:javax.persistence.Table.indexes () khi thực hiện truy vấn JPA

  3. Làm cách nào để khôi phục một bảng từ bản sao lưu .sql postgresql?

  4. Tổng quan về các nút kế hoạch phụ trợ khác nhau trong PostgreSQL

  5. Sự phát triển của khả năng chịu lỗi trong PostgreSQL:Du hành thời gian