2010-02-22 44 views
11

Vì vậy, tôi đang cố gắng tìm ra các phương pháp hay nhất về kết nối cơ sở dữ liệu của mình. Tôi có một NET GUI lớn, đóng vai trò là giao diện người dùng cho db của MySQL. Hiện tại tôi mở một kết nối tải ứng dụng và sử dụng nó cho bất kỳ tương tác nào tôi cần. Tuy nhiên, toàn bộ GUI là đơn luồng.Đa luồng và kết nối cơ sở dữ liệu

Khi tôi bắt đầu thêm BackgroundWorkers cho các truy vấn lớn và thực hiện tôi lo lắng về kết nối mở của mình. Tôi biết, ví dụ, rằng tôi chỉ có thể có một dataReader tại một thời điểm mở trên kết nối đó. Với nhiều chủ đề, người dùng có thể cố gắng để nhanh chóng hơn thế.

Ưu điểm/nhược điểm của việc giữ một kết nối mở cho ứng dụng là gì khi mở một kết nối mới cho mọi tương tác?

Một số mẫu thiết kế phổ biến cho điều này là gì?

Thanks-

Jonathan

Trả lời

6

Sử dụng một kết nối hồ bơi thread-safe và giữ kết nối thread-cụ thể (không chia sẻ kết nối qua đề).

Tôi tin rằng khung kết nối MySQL .NET đi kèm với một built-in. Nếu bạn sử dụng cùng một chuỗi kết nối cho tất cả các kết nối, chỉ cần thêm "pooling = true" vào chuỗi kết nối của bạn. (Source - không có đoạn siêu liên kết, vì vậy hãy tìm "gộp" trong bảng)

Hạn chế của phương pháp này là một số luồng sẽ chặn cho đến khi kết nối khả dụng. Bạn sẽ cần tính đến điều này trong cấu trúc chương trình của bạn.

1

Với một kết nối mở, bạn phải có thông lượng tối đa với cơ sở dữ liệu. Tuy nhiên, bạn sẽ viết mã phức tạp trong ứng dụng của mình để chia sẻ kết nối.

Here là một bài viết về mẫu chia sẻ tài nguyên. Các ví dụ là trong Ada nhưng tôi chắc rằng bạn có thể đọc nó.

1

Kết nối với nguồn dữ liệu có thể tốn thời gian. Để giảm thiểu chi phí của các kết nối mở, ADO.NET sử dụng một kỹ thuật tối ưu hóa được gọi là kết nối tổng hợp, giúp giảm thiểu chi phí của các kết nối mở và đóng liên tục. Kết nối tổng hợp được xử lý khác nhau cho các nhà cung cấp dữ liệu .NET Framework.

từ MSDN.

thấy ở đây Connection Pooling (ADO.NET)

3

Có 2 cách:

  1. kết nối đơn - trong trường hợp này, kết nối được tạo ra 1 lần và được chia trong số tất cả các yêu cầu, rằng nếu một số lượng lớn đồng thời yêu cầu dẫn đến mất năng suất và bạn phải tự kiểm soát việc tiết kiệm luồng.

  2. Kết nối theo yêu cầu - trong trường hợp này, bạn phải mở kết nối và đóng ngay sau khi thực hiện yêu cầu. Nhưng số lượng kết nối mở đồng thời có thể bị giới hạn bởi máy chủ. Ở đây, chi phí tạo kết nối luôn luôn hiện diện, nhưng được giải quyết bằng cách sử dụng kết nối an toàn thread-threading, đó là thực hành tốt.

Bạn cần phân tích và dự đoán hành vi của ứng dụng và chọn đường dẫn thích hợp. Nếu bạn có một ứng dụng đơn giản, có thể bạn sẽ không cần phải sử dụng các hồ bơi. Nếu ứng dụng đòi hỏi một tải trọng nghiêm trọng và khả năng mở rộng trong tương lai, nó sẽ là chính xác để sử dụng các hồ bơi.

0

Chúng tôi đã thực hiện một số kiểm tra trước khi quyết định nên đi đường nào. Tôi có nghĩa là giữa ConnectionAlwaysOpen hoặc ConnectAndDisconnectEachTime. Rõ ràng từ .NET với SQL Server (không bao giờ thử với MySQL) không có hình phạt hiệu suất có thể nhìn thấy trong cả hai cách tiếp cận (không có gì đáng ngạc nhiên, vì các lớp thấp hơn không thực sự ngắt kết nối ngay lập tức trong kịch bản ConnectAndDisconnectEachTime). Nhưng có một sự khác biệt tinh tế khiến chúng tôi quyết định ConnectionAlwaysOpen. Lý do là Hỗ trợ giao dịch. Nếu bạn dự định sử dụng giao dịch thì kết nối/ngắt kết nối sẽ KHÔNG hoạt động, tôi nghĩ đó rõ ràng là lý do tại sao.

ConnectionAlwaysOpen tất nhiên có thể được cải thiện bằng cách sử dụng các hồ bơi kết nối hiện có hoặc một số bộ đệm ẩn thủ công của các nhóm kết nối, nhưng ý tưởng cơ bản vẫn giữ nguyên. Mặt khác, trong ứng dụng Web, việc thực hiện và xử lý an toàn luồng này một chút khó khăn hơn, nhưng nó có thể đáng để nỗ lực.

+0

Khi bạn nói hỗ trợ giao dịch là không thể đối với kịch bản ConnectAndDisconnect, bạn có đang nói về giao dịch "toàn cầu" có hỗ trợ khôi phục mọi thứ kể từ khi ứng dụng được khởi chạy không? Nếu không, ngay cả với ConnectAndDisconnect, bạn có thể có hỗ trợ giao dịch. Bạn phải tổ chức mã của bạn để xác định giao dịch "cấp cao" và sau đó sử dụng ví dụ "TransactionScope" trong C# (http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx) – FrenchData

+0

@FrenchData Tôi đang nói về giao dịch cấp trung gian, đến từ lớp logic nghiệp vụ. Chúng tôi đã thử cách tiếp cận TransactionScope nhưng nó vẫn chưa đủ, chúng tôi nhanh chóng gặp rắc rối, bởi vì mã lớp trung gian được sử dụng theo những cách khác nhau không lường trước được. Giải pháp bằng cách nào đó là một lai giữa hai cách tiếp cận, lớp ConnectionManager của chúng tôi hỗ trợ cả hai cách tiếp cận. Tất nhiên là không cần giao dịch từ khi bắt đầu ứng dụng, đó là lý do giải pháp lai tốt hơn. – AureliusMarcus

Các vấn đề liên quan