Datos reactivos con R2DBC y Spring Data
Secciones
Ajustes de lectura
Ninguna voz para este idioma en este navegador.
Más voces
Código y términos técnicos en inglés
Desactivado: la voz de la página lo lee todo, sin pausa entre dos voces.
Ninguna voz para este idioma en este navegador.
Más voces
Más voces: Microsoft Edge ofrece voces naturales en línea, y Windows (Configuración › Hora e idioma › Voz), macOS y Android instalan otras.
R2DBC es un contrato reactivo para bases de datos. A diferencia de JDBC, no mantiene un hilo bloqueado por consulta. Spring Data R2DBC mapea filas y compone el trabajo como Mono y Flux.
La frontera, no solo el tipo devuelto
Sección titulada «La frontera, no solo el tipo devuelto»Envolver JDBC en Flux<Row> sigue siendo bloqueante. Un controlador R2DBC real produce señales Reactive Streams desde la conexión hasta la decodificación. El módulo usa H2 R2DBC en memoria: la misma prueba funciona en Windows, Linux y macOS sin Docker.
@Table("voicing")public record Voicing(@Id Long id, String symbol, int fret) { public static Voicing newVoicing(String symbol, int fret) { return new Voicing(null, symbol, fret); }}R2dbcEntityTemplate equivale a usar directamente un DbContext de EF Core:
public Mono<Voicing> save(Voicing voicing) { return template.insert(voicing);}
public Flux<Voicing> findBySymbol(String symbol) { return template.select(Voicing.class) .matching(Query.query(Criteria.where("symbol").is(symbol))) .all();}Nada ocurre antes de la suscripción. La prueba encadena esquema, inserciones y selección, y verifica las señales con StepVerifier. block() solo aparece en la preparación de la prueba.
mvn -B -pl l05-r2dbc -am testLas transacciones también son publishers
Sección titulada «Las transacciones también son publishers»Una transacción R2DBC pertenece a una conexión y es asíncrona. La segunda prueba inicia una transacción, inserta G7, revierte y prueba que la consulta siguiente está vacía. Una aplicación suele usar R2dbcTransactionManager y TransactionalOperator; la conexión explícita hace visible el ciclo de vida.
No compartas una conexión mutable entre suscriptores, no ejecutes JDBC en el event loop y no uses un ID generado antes de que termine la inserción. La backpressure controla la entrega, no la capacidad de la base de datos.
Ejercicios
Sección titulada «Ejercicios»- Añade
findAtOrAboveFret(int fret)y ordena por traste.
Solución
Usa Query.query(Criteria.where("fret").greaterThanOrEquals(fret)).sort(Sort.by("fret")) y verifica el orden con StepVerifier.expectNextMatches.
- Inserta dos filas en una transacción, fuerza un error y demuestra que no queda ninguna.
Solución
Compón ambos statements en la misma conexión, añade Mono.error y aplica onErrorResume solo después de rollbackTransaction(). El invariante es la atomicidad.
- ¿Cuándo es más sencillo JDBC sobre hilos virtuales?
Solución
Elige JDBC si el driver, el ORM y el equipo son bloqueantes y la concurrencia es moderada. Elige R2DBC si todo el camino es reactivo y la concurrencia consumiría demasiados hilos bloqueados.