2016-08-18 15 views
8

Tôi đang chạy một ứng dụng sử dụng Hibernate trên máy chủ Tomcat 8. Tôi muốn sử dụng một hồ bơi kết nối khác với Hibernate bởi vì họ làm cho nó khá rõ ràng rằng nó không thích hợp để sử dụng trong một môi trường sản xuất.Tại sao sử dụng C3PO và JNDI đồng thời tạo ra một vấn đề?

Ngoài ra, họ kể rằng:

Để sử dụng bên trong một máy chủ ứng dụng, bạn hầu như luôn luôn nên cấu hình Hibernate để có được kết nối từ một javax.sql.DataSource máy chủ ứng dụng đăng ký tại JNDI.

Vì vậy, có vẻ như tôi cần phải làm hai việc:

  1. Cấu hình Hibernate để làm việc với một hồ bơi kết nối của bên thứ ba - Hibernate khuyến C3PO
  2. Cấu hình Hibernate để có được kết nối từ một đối tượng javax.sql.Datasource đã đăng ký tại JNDI

Tôi đã nghiên cứu để xem cách thực hiện những thay đổi này và tôi đã xem qua this SO câu hỏi. Các poster đã được sử dụng C3PO và được hỏi làm thế nào để kết nối với cơ sở dữ liệu của họ thông qua một đối tượng JNDI Datasource. Tuy nhiên, họ gặp vấn đề bởi vì họ đã sử dụng C3PO trong khi họ đang làm theo các bước của người trả lời để sử dụng Datasource JNDI. Người đăng ký đã nói điều này trong phần nhận xét của câu trả lời được chấp nhận:

vâng đúng, tôi đã làm sth thực sự ngớ ngẩn trong đó sử dụng cả c3p0 và JNDI. Tôi đã gỡ bỏ tất cả các cấu hình c3p0 và nó hoạt động tốt ngay bây giờ.

Hibernate khuyến nghị sử dụng nhóm kết nối của bên thứ ba, cụ thể là C3PO và sử dụng nguồn dữ liệu JNDI để nhận kết nối, và dường như gây ra sự cố cho người dùng này; và họ thậm chí còn đi xa đến mức nói về việc sử dụng cả hai cùng một lúc như thể đó là một sai lầm rõ ràng.

Vì vậy, tôi có thể không sử dụng cả hai cùng một lúc, hoặc tôi nên, như Hibernate khuyến cáo? Tất cả những gì tôi đang cố gắng làm là thay thế hồ bơi kết nối mặc định của Hibernate bằng một hồ bơi được thiết kế để sử dụng trong môi trường sản xuất và cấu hình Hibernate để lấy các kết nối từ đối tượng javax.sql.Datasource được đăng ký trong JNDI.

Trả lời

2

Tôi sẽ cố gắng dọn dẹp sự nhầm lẫn.

Tôi nghĩ rằng nó bắt đầu với giao diện DataSource đáng ngạc nhiên đơn giản: https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html

Giao diện DataSource được thực hiện bởi một nhà cung cấp trình điều khiển. Có ba loại hiện thực:

  1. thực hiện cơ bản - tạo ra một đối tượng Connection chuẩn
  2. thực hiện kết nối tổng hợp - tạo ra một đối tượng Connection sẽ tự động tham gia kết nối tổng hợp. Triển khai này hoạt động với trình quản lý tổng hợp kết nối cấp trung bình.
  3. Triển khai giao dịch phân tán - tạo đối tượng Kết nối có thể được sử dụng cho các giao dịch được phân phối và hầu như luôn luôn tham gia vào kết nối tổng hợp. Triển khai này hoạt động với trình quản lý giao dịch cấp trung bình và hầu như luôn có kết nối trình quản lý tổng hợp.

Hibernate cần nguồn dữ liệu để làm việc và khuyến nghị sử dụng kết nối tổng hợp.

C3PO kết thúc một nguồn dữ liệu hiện có và áp dụng kết nối tổng hợp với nó, và tạo ra một nguồn dữ liệu mới là loại 2. C3PO giả định rằng DataSource nó nhận được loại 1, nhưng nó không thể chắc chắn.

Trong các máy chủ ứng dụng khác, nếu bạn khai báo nguồn dữ liệu được đăng ký trong JNDI, nó hầu như luôn sử dụng kết nối tổng hợp đã có trong vùng chứa. Trong trường hợp của Tomcat 8, nó sử dụng C3PO trong nội bộ.Vì vậy, có hai cách để đạt được kết nối tổng hợp trong Hibernate: hoặc tạo nguồn dữ liệu kiểu 1 và nhúng nó vào một nhóm kết nối trong mã, hoặc khai báo nguồn dữ liệu của bạn (với pool kết nối) trong thùng chứa và tiêm nó trong hibernate từ JNDI.

Nếu bạn làm cả hai, như trong trường hợp của bạn, C3PO trong ứng dụng của bạn nhận được nguồn dữ liệu từ JNDI, đó chính là một C3PO DataSource do tomcat quản lý. Khi ứng dụng cố gắng để có được một kết nối, ứng dụng C3PO sẽ gọi C3PO container, mà sẽ tạo ra các kết nối thực tế, nhưng kết nối sẽ được gộp lại trong cả hai hồ bơi kết nối. Khi hibernate phát hành kết nối, ứng dụng C3PO sẽ giữ nó để tái sử dụng, nhưng hồ bơi kết nối khác sẽ tiếp tục chờ đợi cho kết nối được phát hành là tốt.

Tùy thuộc vào cấu hình, nhóm kết nối bên dưới có thể có thể hủy kết nối sau một thời gian chờ nhất định.

Vì vậy, việc định cấu hình hai nhóm kết nối trên đầu trang của nhau là nguy hiểm và hoàn toàn không cần thiết.

Để trả lời câu hỏi tiền thưởng: trong môi trường sản xuất, khai báo nguồn dữ liệu trong thùng chứa sản phẩm của bạn và kết nối nó với Hibernate qua JNDI mà không cần thêm cấu hình kết nối trong Hibernate.

1

Trong bài viết SO tham chiếu, áp phích bắt đầu bằng C3PO đã được cấu hình bởi Hibernate. Khi áp phích chuyển sang nhận tham chiếu JNDI đến đã được cấu hình hồ bơi kết nối C3PO, anh/cô ấy nghĩ cấu hình đã được xử lý bởi Hibernate trong quá trình khởi động. Giải pháp là di chuyển cấu hình C3PO vào thùng chứa (Tomcat) và xóa cấu hình khỏi cài đặt Hibernate.

Dưới đây là một phác thảo đơn giản hóa các ứng dụng khởi động:

  • container thực hiện các hoạt động khởi động của nó
    • Tạo kết nối và bắt đầu nghe cho các kết nối
    • Tạo và cấu hình nguồn JNDI như, phiên email DataStore của , v.v.
  • Triển khai ứng dụng web
    • Scan cho một ứng dụng web
    • Cấu hình ứng dụng web
    • Cung cấp bất kỳ tài nguyên JNDI quy định trong cấu hình triển khai
    • Hoàn

Đó là trong giai đoạn triển khai các ứng dụng web mà Cấu hình Hibernate được đọc và yêu cầu cho một tài nguyên JNDI được thực hiện. Kể từ C3PO đã được cấu hình, bất kỳ cấu hình được thực hiện trong Hibernate không được nhìn thấy.

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