2016-11-18 23 views
14

Tôi biết có những câu hỏi tương tự về kịch bản này, tuy nhiên không có câu hỏi nào trong số đó phù hợp với trường hợp của tôi và tôi muốn có giải pháp không ảnh hưởng đến hiệu suất. Tôi phải thực hiện nhiều kết nối tới các cơ sở dữ liệu khác nhau (tất cả postgresql) và vấn đề là các cơ sở dữ liệu có thể nhiều khi chúng liên tục được tạo ra.Hibernate nhiều kết nối tự động thay đổi

Hiện tại, tôi chỉ có một cơ sở dữ liệu đã biết sẽ được sử dụng để lưu trữ các chuỗi kết nối từ các cơ sở dữ liệu khác. Các cơ sở dữ liệu này có thể là 1, 2, 5, 10 hoặc N, phần khôn lanh là từ phần cuối của tôi, tôi sẽ không bao giờ biết số lượng chúng sẽ là bao nhiêu và vị trí và thông tin của chúng sẽ là gì (tất cả được lưu trữ trên DB trung tâm của tôi). Trường hợp sử dụng hoạt động theo cách để thực hiện một thao tác trên một trong các cơ sở dữ liệu này, trước tiên tôi phải lấy từ cơ sở dữ liệu trung tâm vị trí cho DB mà chúng ta cần và sau đó thực hiện thao tác.

Hiện tại, tôi có thể thực hiện thao tác bằng cách hát SessionFactory, nhưng thao tác quá chậm ngay cả khi chọn/cập nhật đơn giản và tôi lo ngại rằng khi có nhiều yêu cầu, chúng tôi có thể nhận được từ Hibernate một Out of Memory Exception.

Bất kỳ ý tưởng nào về cách tiếp cận tốt nhất cho trường hợp này là gì?

+0

http://stackoverflow.com/questions/8572469/hibernate-multi-tenant -auto-creation-of-tables Có thể có giải pháp cho vấn đề của bạn –

+0

Bỏ phiếu trên cơ sở dữ liệu chủ cho cơ sở dữ liệu và tạo kết nối háo hức có thể là một tùy chọn. Bạn có thể thử sử dụng một hồ bơi kết nối cho mỗi cơ sở dữ liệu. – mm759

Trả lời

0

Theo kinh nghiệm của tôi, tôi đã làm việc với nhiều lược đồ từ một cơ sở dữ liệu duy nhất. Hibernate cần tạo nhiều EntityManagerFactory cho mỗi lược đồ duy nhất và cũng cho mọi cơ sở dữ liệu.

Bạn cần một EntityManagerFactory cho mọi lược đồ hoặc mọi cơ sở dữ liệu bạn đang làm việc.
Và bạn biết có được một EntityManagerFactory rất tốn kém về mặt tài nguyên và thời gian.
Sau đó, có một EntityManager đơn lẻ rất rẻ.

Vì vậy, trong trường hợp của bạn, Bạn phải tạo một N EntityManagerFactory, một trong số chúng cho mỗi Cơ sở dữ liệu khác nhau hoặc lược đồ khác nhau từ cùng một cơ sở dữ liệu.

Vì nó là tốn kém để tạo EntityManagerFactory, bạn phải tạo chúng chỉ khi cần thiết và khi cần thiết, và bạn biết rằng bạn phải chờ gần 30 giây hoặc hơn để có được tất cả mọi người trong số họ.

Để tránh ngoại lệ ngoài bộ nhớ, bạn có thể thử kiểm tra để tạo từ 1 đến N, số lượng tối đa của EntityManagerFactory và xem liệu tài nguyên của bạn có thể hỗ trợ điều này hay không.

Nếu bạn thấy rằng khi bạn đến số X và hệ thống này luôn luôn sụp đổ, vì vậy bạn có thể giới hạn số lượng đồng thời EntityManagerFactory với số giới hạn X này.

Hãy thử và cho tôi biết kết quả của bạn hoặc nếu bạn cần một số mã ví dụ

0

Tôi đã suy nghĩ về vấn đề này theo một cách khác một chút.

Theo hiểu biết của tôi

yêu cầu của bạn là để lấy dữ liệu từ cơ sở dữ liệu khác nhau, thậm chí bạn không biết tại thời điểm phát triển.

Vì vậy, lý do tại sao bạn đang cố gắng đặt tất cả tải này trên chế độ ngủ đông để quản lý kết nối với nhiều cơ sở dữ liệu.

Bạn biết rõ cơ sở dữ liệu chính là vậy.

Để cơ sở dữ liệu chính thực hiện mọi việc còn lại.

Bạn chỉ nên giao tiếp với cơ sở dữ liệu chính và tất cả gánh nặng để tìm nạp dữ liệu từ cơ sở dữ liệu phải được lưu trữ trên cơ sở dữ liệu chính.

Tạo DBLinks cho các cơ sở dữ liệu khác nhau bên trong cơ sở dữ liệu chính.

Và duy trì siêu dữ liệu bắt buộc cũng như trong cơ sở dữ liệu chính.

Bất cứ khi nào bạn cần tìm nạp dữ liệu từ bất kỳ cơ sở dữ liệu mới được thêm vào nào hoặc như vậy, chỉ được hỏi từ cơ sở dữ liệu chính.

vấn đề có thể được giải quyết bằng cách sử dụng DBLinks

  • Bạn không cần phải để lộ thông tin cơ sở dữ liệu (cơ sở dữ liệu khác nhau) trong bất kỳ bảng
  • Hibernate sẽ được giữ ánh sáng trọng
  • Mã Java của bạn sẽ được giữ sạch
  • Bất kỳ thay đổi nào được thực hiện trong bất kỳ cơ sở dữ liệu nào (cấu trúc, thông tin xác thực) sẽ phản ánh ngay lập tức (Trong cách tiếp cận khác, bạn cần phải resta rt ứng dụng của bạn sau khi bất kỳ thay đổi như vậy trong cơ sở dữ liệu)

A reference for DBLink in postgres

0

Chúng tôi có những điều tương tự: 1..N cơ sở dữ liệu như khách hàng khác nhau. Mỗi khách hàng có cùng một lược đồ để chúng tôi chỉ có 1 người quản lý thực thể. SO bạn cần cung cấp cho hibernete qua spi 2 lớp thực hiện và handen qua thuộc tính:

hibernate.multi_tenant_connection_provider org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider

hibernate.tenant_identifier_resolver org.hibernate.context.spi.CurrentTenantIdentifierResolver

"hibernate.multiTenancy", "SCHEMA"

Dưới đây là ví dụ làm thế nào để làm điều đó với khuôn khổ mùa xuân

LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
    emf.setJpaVendorAdapter(jpaVendorAdapter()); 
    emf.setPersistenceUnitName("security"); 
    Properties hibernateProperties = new Properties(); 
    hibernateProperties.put("hibernate.cache.use_second_level_cache", "true"); 
    hibernateProperties.put("hibernate.multiTenancy", "SCHEMA"); 
    // do not load all metadata from standard db speadup startup 
    hibernateProperties.put("hibernate.temp.use_jdbc_metadata_defaults", "false"); 
    hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect"); 
    hibernateProperties.put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProvider()); 
    hibernateProperties.put("hibernate.tenant_identifier_resolver", currentTenantIdentifierResolver(tenant)); 
    hibernateProperties.put("hibernate.show_sql", true); 
    emf.setJpaProperties(hibernateProperties); 
    emf.setJpaDialect(new HibernateJpaDialect()); 
    LOG.info("LocalContainerEntityManagerFactoryBean bean created"); 
    return emf; 
Các vấn đề liên quan