Ist es möglich, in Hibernate den Befehl WRITE BATCH NOWAIT auszuführen?
Ich habe nicht ausführlich gesucht, aber ich konnte keinen Hinweis finden, dass Sie auf der JDBC-Treiberebene auf diese Funktionalität zugreifen können.
Damit haben Sie die Möglichkeit, den Parameter COMMIT_WRITE
auf Instanz- oder Sitzungsebene anzugeben, wenn dies für Sie sinnvoll ist.
Nur für den Fall, lassen Sie mich diesen Blogbeitrag zitieren (ich füge den Inhalt als Referenz ein, weil die ursprüngliche Seite entweder nicht verfügbar oder tot ist und ich Google Cache verwenden musste):
Verwenden von" Commit Write Batch Nowait "aus JDBC
Wer hat das Neue benutzt? asynchrone Festschreibungsfunktion von Oracle 10.2 wird wissen, dass es für die Transaktionsverarbeitung sehr nützlich ist Systeme, die traditionell sein würden gebunden an
log_file_sync
wait events.
COMMIT WRITE BATCH NOWAIT
ist schneller weil es nicht auf eine Nachricht wartet versichern, dass die Transaktion ist sicher im redo log - stattdessen es geht davon aus, dass es es schaffen wird. Das ist fast eliminiertlog_file_sync
-Ereignisse. Es das untergräbt wohl auch das Ganze Zweck des Commit, aber es gibt viele Situationen, in denen der Verlust von a bestimmte Transaktion (sagen wir zu löschen eine abgeschlossene Sitzung) ist perfekt überlebensfähig und viel vorzuziehen als nicht in der Lage zu sein, eingehende zu bedienen Anfragen wegen all Ihrer Verbindungen sind beschäftigt mitlog_file_sync
wait Ereignisse.Das Problem, dass jemand JDBC von Oracle verwendet Treiber ist, dass weder die 10.2 oder 11.1 Treiber haben alle Erweiterungen, mit denen Sie auf diese Funktionalität zugreifen können leicht - während Oracle viele haben herstellerspezifische Erweiterungen für alle Arten von Dingen unterstützen asynchrone Commit fehlt.
Das bedeutet, Sie können:
Aktivieren Sie das asynchrone Commit auf Instanzebene, indem Sie mit dem
COMMIT_WRITE
init.ora
Parameter. Das ist eine wirklich gute Chance Sie werden gefeuert, wie überall gesamtes System COMMIT wird sein asynchron. Während wir denken, dass das ist verrückt nach Produktionssystemen dort sind Zeiten, in denen es auf a gesetzt wird Entwicklungsbox macht Sinn, als ob Sie sind 80% Protokolldatei-Synchronisierung gebundene EinstellungCOMMIT_WRITE
, um WRITE BATCH zu COMMITIEREN NOWAIT wird Ihnen erlauben, was zu sehen Probleme, denen Sie begegnen, wenn Sie irgendwie können repariere deine aktuellen.Ändern Sie
COMMIT_WRITE
auf der Sitzungsebene. Dies ist nicht so gefährlich wie tut es systemweit, aber es ist schwer zu sehe es für eine reale Welt lebensfähig System mit Transaktionen Menschen kümmern ungefähr.Bereiten Sie einen PL / SQL-Block vor, der "BEGIN COMMIT WRITE BATCH NOWAIT; END ". Das ist sicherer als das erste zwei Ideen, aber immer noch ein Netzwerk Rundreise.
Umbrechen Sie Ihre Anweisung in einen anonymen Block mit einem asynchronen Commit. Dies ist der beste Ansatz, den wir gesehen haben. Ihr Code sieht ungefähr so aus das:
%Vor%
Ich habe nach einer Möglichkeit gesucht, dies zu tun, aber ich konnte es nicht in einem Test arbeiten lassen. Der Grund für mein Halten war, dass ich die falschen Ergebnisse von meinem Test erwartet hatte. Ich testete, indem ich manuell eine gemeinsame Tabellensperre erlangte, um das Hinzufügen eines Indexes zu simulieren - aber in diesem Fall erwirbt die Abfrage insert
die Sperre, nicht commit
. Es löst also nicht das Problem, das ich lösen wollte. Ich habe mein Problem gelöst, indem ich diese Einfügungen in eine Hintergrundwarteschlange verschoben habe, so dass sie die Haupt-Webanforderung nicht halten.
Wie auch immer, ich denke, Sie können in Hibernate immer noch asynchrone Commits machen. Grundsätzlich können Sie die Methode Session.doWork()
verwenden, um auf das native Objekt Connection
zuzugreifen (oder in älteren Versionen von Hibernate die Methode Session.connection()
). Ich habe auch die Commit-SQL in eine Strategie-Schnittstelle verschoben, so dass wir unsere HSQLDB-basierten Tests ausführen können, die das Oracle-spezifische SQL nicht verstehen.
Tatsächlich ist es in Ordnung, Session.createSQLQuery
zu verwenden und das SQL anzugeben, ohne Connection
direkt verwenden zu müssen. Probieren Sie es aus und sehen Sie, wie es funktioniert.