Warum verursacht die gleichzeitige Verwendung von C3PO und JNDI ein Problem?

8

Ich führe eine Anwendung aus, die Hibernate aus einem Tomcat 8-Server heraus verwendet. Ich möchte einen anderen Verbindungspool als den von Hibernate verwenden, da es ziemlich offensichtlich macht, dass es nicht für den Einsatz in einer Produktionsumgebung geeignet ist.

Auch erwähnen sie das:

  

Für die Verwendung innerhalb eines Anwendungsservers sollten Sie fast immer Hibernate konfigurieren, um Verbindungen von einem in JNDI registrierten Anwendungsserver javax.sql.Datasource zu erhalten.

So scheint es, dass ich zwei Dinge tun muss:

  1. Konfigurieren von Hibernate für die Arbeit mit einem Verbindungspool eines Drittanbieters - Hibernate empfiehlt C3PO
  2. Konfigurieren Sie Hibernate, um Verbindungen von einem javax.sql.Datasource -Objekt zu erhalten, das in JNDI registriert ist

Ich habe recherchiert, um zu sehen, wie ich diese Änderungen vornehmen kann, und ich stieß auf diese SO Frage. Das Poster verwendet bereits C3PO und fragt, wie man sich über ein JNDI Datasource -Objekt mit ihrer Datenbank verbinden kann. Sie hatten jedoch Probleme, weil sie C3PO bereits verwendeten, während sie die Schritte des Beantworters zur Verwendung der JNDI-Datenquelle befolgten. Das Plakat sagte dies im Kommentarbereich der angenommenen Antwort:

  

Ja, richtig, ich habe da wirklich blöd mit c3p0 und JNDI gearbeitet. Ich entfernte alle c3p0 Konfigurationen und es funktioniert jetzt gut.

Hibernate empfiehlt die Verwendung eines Verbindungspools eines Drittanbieters, nämlich C3PO, und die Verwendung einer JNDI-Datenquelle, um Verbindungen zu erhalten, und dennoch schien es für diesen Benutzer ein Problem zu verursachen; und sie gehen sogar so weit, dass sie beide gleichzeitig benutzen, als wäre es ein offensichtlicher Fehler.

Also kann ich sie nicht beide zur selben Zeit benutzen, oder sollte ich, wie Hibernate es empfiehlt? Alles, was ich versuche, ist, den Standard-Verbindungspool von Hibernate durch einen Pool zu ersetzen, der für Produktionsumgebungen gedacht ist, und Hibernate, um Verbindungen von einem in JNDI registrierten javax.sql.Datasource -Objekt zu erhalten, wie sie empfehlen.

>     
the beest 18.08.2016, 21:49
quelle

2 Antworten

2

Ich werde versuchen, die Verwirrung zu beseitigen.

Ich denke, es beginnt mit der überraschend einfachen DataSource-Schnittstelle: Ссылка

  

Die DataSource-Schnittstelle wird von einem Treiberhersteller implementiert. Es gibt   drei Arten von Implementierungen:

     
  1. Grundlegende Implementierung - erzeugt ein Standard-Verbindungsobjekt
  2.   
  3. Verbindungspoolimplementierung - erstellt ein Connection-Objekt, das automatisch am Verbindungspooling teilnimmt. Dies   Implementierung funktioniert mit einem Verbindungsmanager der mittleren Schicht.
  4.   
  5. Verteilte Transaktionsimplementierung - erzeugt ein Connection-Objekt, das fast immer für verteilte Transaktionen verwendet werden kann   nimmt am Verbindungspooling teil. Diese Implementierung funktioniert mit a   Middle-Tier-Transaktionsmanager und fast immer mit einer Verbindung   Pooling Manager.
  6.   

Hibernate benötigt eine DataSource, mit der er arbeiten kann, und empfiehlt, dass er Verbindungspooling verwendet.

C3PO umschließt eine vorhandene DataSource und wendet das Verbindungspooling darauf an und erstellt eine neue DataSource vom Typ 2. C3PO geht davon aus, dass es sich bei der DataSource um Typ 1 handelt, kann aber nicht sicher sein.

Wenn Sie auf anderen Anwendungsservern eine Datenquelle deklarieren, die in JNDI registriert ist, verwendet sie fast immer Verbindungspooling, das sich bereits im Container befindet. Im Fall von Tomcat 8 verwendet es intern C3PO.

Es gibt also zwei Möglichkeiten, das Verbindungs-Pooling in Hibernate zu erreichen: Entweder erstellen Sie eine Datenquelle vom Typ 1 und betten sie in einen Verbindungspool ein oder deklarieren Sie Ihre Datenquelle (mit Verbindungspool) im Container und injizieren sie in den Ruhezustand JNDI.

Wenn Sie beides tun, wie in Ihrem Fall, erhält der C3PO in Ihrer Anwendung eine Datenquelle von JNDI, die wiederum eine von Tomcat verwaltete C3PO DataSource ist. Wenn die Anwendung versucht, eine Verbindung herzustellen, ruft die Anwendung C3PO den Container C3PO auf, der die tatsächliche Verbindung erstellt, die Verbindung wird jedoch in beiden Verbindungspools zusammengefasst. Wenn Hibernate die Verbindung freigibt, behält die Anwendung C3PO sie zur Wiederverwendung bei, aber der andere Verbindungspool wartet weiterhin auf die Freigabe der Verbindung.

Abhängig von der Konfiguration kann der zugrunde liegende Verbindungspool möglicherweise die Verbindung nach einer bestimmten Zeitüberschreitung beenden.

Das Konfigurieren von zwei Verbindungspools übereinander ist gefährlich und völlig unnötig.

Um die Kopfgeldfrage zu beantworten: Deklarieren Sie in Produktionsumgebungen die Datenquelle in Ihrem Produktionscontainer und verbinden Sie sie über JNDI mit Hibernate, ohne dass ein zusätzliches Verbindungspooling in Hibernate konfiguriert ist.

    
greyfairer 14.09.2016, 14:37
quelle
1

Im Referenz-SO-Post beginnt das Poster mit C3PO, das bereits von Hibernate konfiguriert wurde. Als das Poster dazu überging, einen JNDI-Verweis auf einen bereits konfigurierten C3PO-Verbindungspool zu erhalten, dachte er, dass die Konfiguration während des Starts von Hibernate verarbeitet wurde. Die Lösung bestand darin, die C3PO-Konfiguration in den Container (Tomcat) zu verschieben und die Konfiguration aus den Hibernate-Einstellungen zu entfernen.

Hier ist eine vereinfachte Übersicht über den Anwendungsstart:

  • Container führt seine Startvorgänge aus
    • Erstellen Sie eine Verbindung und beginnen Sie, auf Verbindungen zu horchen
    • Erstellen und konfigurieren Sie JNDI-Ressourcen wie DataStore, Mail-Sitzungen usw.
  • Stellen Sie Webanwendungen bereit
    • Nach einer Webanwendung suchen
    • Konfigurieren Sie die Webanwendung
    • Geben Sie JNDI-Ressourcen an, die während der Konfiguration angegeben wurden
    • Beenden Sie die Bereitstellung

Während der Bereitstellungsphase der Webanwendungen wird die Hibernate-Konfiguration gelesen und die Anforderung für eine JNDI-Ressource ausgeführt. Da C3PO bereits konfiguriert ist, wird keine in Hibernate vorgenommene Konfiguration angezeigt.

    
walsht 13.09.2016 15:45
quelle

Tags und Links