2009-03-16 9 views
5

Tôi đang cố gắng ghi lại việc tạo và hủy các kết nối cơ sở dữ liệu trong ứng dụng của chúng tôi bằng cách sử dụng số ConnectionCustomizer của c3p0. Trong đó, tôi có một số mã trông giống như sau:Đặt hàng Khóa trong C3p0

log(C3P0Registry.getPooledDataSources()) 

Tôi đang chạy vào deadlocks. Tôi phát hiện ra rằng c3p0 có ít nhất một vài đối tượng trong thư viện của nó sử dụng các phương thức được đồng bộ hóa, và dường như không chỉ định thứ tự khóa dự định của chúng. Khi tôi đăng nhập các kết nối, tôi đang giữ một khóa trên C3P0Registry và cuối cùng là PoolBackedDataSource (chỉ cần tạo danh sách các nguồn dữ liệu đang truy cập vào mã băm gây ra khóa).

Tắt nhà cung cấp kết nối (gọi số C3P0ConnectionProvider.close()) khiến các khóa được gọi theo thứ tự ngược lại. Nhưng trong khi các nguồn dữ liệu con đang bị tắt, quá trình ghi nhật ký của tôi đang được kích hoạt. Kết quả là một bế tắc.

Nó có vẻ như cả hai cuộc gọi tôi đang làm vào thư viện C3P0 có giá trị, các cuộc gọi mong đợi:

  • C3P0ConnectionProvider.close()
  • C3P0Registry.getPooledDataSources()

Nó cũng có vẻ như (trừ trường hợp quy định rõ ràng trong tài liệu) nó phải là trách nhiệm của thư viện để quản lý chiến lược khóa riêng của nó. (Tôi không nói điều này để đổ lỗi cho bất cứ ai .. chỉ để xác nhận sự hiểu biết của tôi về các phương pháp hay nhất)

Tôi nên giải quyết vấn đề này như thế nào? Vì c3p0 sử dụng các phương thức được đồng bộ hóa chứ không phải là một cơ chế hiện đại hơn, tôi thực sự không thể kiểm tra các khóa.

Từ mã số DataSource của tôi, trước tiên tôi có thể lấy khóa C3P0Registry trước khi đóng DataSource. Tôi sẽ đoán đúng thứ tự khóa mà tôi không biết liệu tôi có cảm thấy thoải mái không.

Tôi không nghĩ rằng tôi có thể đảo ngược thứ tự khóa cho cuộc gọi ghi nhật ký. Tôi cần số C3P0Registry để lấy danh sách DataSources, vì vậy tôi không thể khóa DataSources mà không cần khóa đầu tiên C3P0Registry để nhận tài liệu tham khảo cho họ.

Một giải pháp khác, tất nhiên là cung cấp một giải pháp khác, khóa cấp cao hơn trên mọi thứ c3p0. Trong trường hợp của một hồ bơi kết nối, có vẻ như để đánh bại các điểm.

Hiện tại, tôi đang khôi phục nhật ký của mình. Cảm ơn vì bất kì sự giúp đỡ.

+0

Trải nghiệm điều gì đó tương tự, quan tâm đến việc bạn có tìm thấy thêm thông tin về điều này hay không. –

+0

Tôi đã kết thúc việc thêm một khối đồng bộ xung quanh mã gọi close() để đảm bảo rằng tôi nhận được khóa theo thứ tự giống như nhật ký của tôi. Đó là cẩu thả, nhưng sau đó một lần nữa, như vậy là chiến lược khóa trong C3p0. –

Trả lời

0

Tôi không biết cách khắc phục vấn đề về khóa, nhưng tôi nghĩ bạn nên lùi lại một bước và suy nghĩ về vấn đề ban đầu. "Tôi đang cố gắng ghi lại việc tạo và hủy kết nối cơ sở dữ liệu trong ứng dụng của chúng tôi ..."

Tôi khuyên bạn nên làm như sau.

Tạo một lớp và làm cho nó triển khai javax.sql.DataSource. Tạo một trường cùng loại và ủy quyền tất cả các phương thức cho nó. Trong phương thức getConnection() trả về lớp kết nối của riêng bạn, gói xung quanh java.sql.Connection và vân vân. Sau đó, quấn lớp này quanh nguồn dữ liệu gốc của bạn. Trong các lớp học, bây giờ bạn có thể tạo một trình ghi nhật ký và ghi lại tất cả các hành động mà bạn muốn xem trong nhật ký của mình.