Auf der Spring One 2018 stellte Pivotal eine API namens R2DBC für den Zugriff auf relationale Datenbanken mit Reactive Streams vor. R2DBC steht für „Reactive Relational Database Connectivity“. Pivotal versucht mit dieser API die Vorteile reaktiver Programmierung auf Systeme mit relationalen Datenbanken zu übertragen. Im Artikel stelle ich R2DBC genauer vor und erläutere, warum es in Zukunft von Bedeutung sein könnte.
Reaktive Programmierung
Das Reactive Manifesto definiert ein reaktives System als ein System, das „responsive, resilient, elastic and message driven“ ist. Das System soll demnach also schnelle Antworten liefern, auch bei Fehlern weiterhin verfügbar und bedienbar bleiben und mit wechselndem Workload zurechtkommen. Ein Kernaspekt vieler reaktiver Systeme ist es daher, mit asynchronen Datenströmen zu arbeiten, um nicht auf blockierende Aktionen warten zu müssen. Wird in einem reaktiven System beispielsweise auf eine Datei zugegriffen oder eine Anfrage an einen Server geschickt, so muss das System nicht auf eine Antwort warten, sondern kann parallel andere Aktionen ausführen. Sobald es eine Antwort erhält, kann die Verarbeitung des Datenstroms fortgeführt werden.
Durch die asynchrone Verarbeitung von Datenströmen wird also die Effizienz eines Systems erhöht. In modernen Architekturen, die häufig stark verteilt aufgebaut sind, gewinnt reaktive Programmierung daher auch immer mehr an Bedeutung. Deshalb unterstützen auch immer mehr Sprachen und Frameworks reaktive Programmierung. So gibt es beispielsweise seit Java SE 9 die Flow API, die reaktive Programmierung in Java ermöglicht. Zusätzlich existieren im Java Umfeld einige bekannte Libraries wie beispielsweise Vert.x, Akka Streams oder RxJava, die reaktive Programmierung beispielsweise mittels Callbacks oder FutureObjects ermöglichen.
Reaktive Programmierung im Spring Umfeld
Auch bei Spring gibt es bereits seit einiger Zeit Ansätze zur reaktiven Programmierung. Seit Spring 5 sind diese Ansätze bereits in Spring Data enthalten, allerdings nur für spezielle NoSQL-Datenbanken. Viele Spring-Anwendungen basieren jedoch noch auf relationalen Datenbanken. Das Problem relationaler Datenbanken ist, dass diese den Datenfluss bei reaktiver Programmierung stoppen. Der Rest der Anwendung kann also reaktiv implementiert sein, dies bringt jedoch kaum Vorteile, wenn der Datenbankzugriff immer noch blockierend ist. Im Spring-Umfeld wird bislang JDBC (Java Database Connectivity) für den Zugriff auf relationale Datenbanken genutzt. Damit ist ein nicht-blockierender Zugriff jedoch nicht sauber möglich.
Mit R2DBC bietet Pivotal jetzt eine Alternative an, welche speziell für die reaktive Programmierung entwickelt wurde. R2DBC stellt den Entwicklern die nötigen Methoden zur Verfügung, um nicht-blockierende Zugriffe auf relationale Datenbanken durchzuführen. Damit lassen sich Systeme mit bestehenden relationalen Datenbanken in Zukunft reaktiv machen.
Im folgenden Beispiel wird gezeigt, wie mit R2DBC asynchrone Transaktionen auf einer PostgreSQL-Datenbank durchgeführt werden können:
Wie zu sehen ist, werden die Ergebnisse der Transaktionen asynchron abgerufen. Das System muss also nicht auf die Ausführung der einzelnen Statements warten. Die hierbei verwendeten Methoden (thenMany, subscribe) sind Methoden aus der ProjectReactor Library, die als Grundlage für R2DBC genutzt wird.
Einschätzung
R2DBC ist nicht der einzige Weg, asynchronen Zugriff auf relationale Datenbanken zu ermöglichen. Alternativ gibt es beispielsweise die Oracle ADBA (Asynchronous Database Access API), die ebenfalls dafür entworfen wurde, nicht-blockierenden Zugriff auf relationale Datenbanken zu ermöglichen. Im Gegensatz zu R2DBC nutzt ADBA allerdings nicht die Flow API von Java 9, sondern CompletableFuture-Objekte, die nach Meinung der R2DBC-Ersteller keine richtige reaktive Programmierung ermöglichen. Daher soll das R2DBC-Projekt laut Pivotal in Zukunft auch eher als Beispiel für Oracle dienen, das zeigt, wie bei ADBA reaktive Programmierung umgesetzt werden könnte. Die Entwickler würden nämlich lieber die zukünftige Entwicklung von ADBA beeinflussen, statt eine eigene Library mit ähnlichen Funktionen weiterzuentwickeln.
R2DBC ist also als Experiment zu verstehen und wurde somit auch noch nicht vollständig umgesetzt. Beispielsweise werden momentan nur PostgreSQL- und H2-Datenbanken unterstützt, und es fehlen noch wichtige Features. Daher sollte R2DBC auch noch nicht im Produktivbetrieb eingesetzt werden. Aktuell kann R2DBC also nur genutzt werden, um Testapplikationen zu erstellen und sich mit dem Konzept der reaktiven Programmierung im Umfeld relationaler Datenbanken vertraut zu machen. Ob und wann das Projekt in Zukunft so weit ist, produktiv eingesetzt zu werden, bleibt abzuwarten. Der Ansatz bleibt aber vielversprechend und könnte (auch durch den Einfluss auf ADBA) in Zukunft durchaus dazu beitragen, reaktive Programmierung auch mit relationalen Datenbanken voranzutreiben.