Tengo un servicio Spring Boot donde tenemos proyectos, colaboradores y una relación de muchos a muchos entre proyectos y colaboradores, esto se modela en JPA como 3 entidades separadas, Project, Contributor y ProjectContributor. Estoy usando Spring Data para interactuar con la base de datos que está en Postgres.
Tras el consumo de un evento de SQS, hay momentos en los que tenemos que crear miles de proyectos en la base de datos junto con sus colaboradores. Estos proyectos y colaboradores son proporcionados por algunos servicios externos.
En el escenario en el que tenemos que crear 1000 proyectos y cada proyecto tiene un promedio de 2 colaboradores, realizo las siguientes llamadas a la base de datos a través de los métodos de guardado del repositorio Spring Data para cada entidad.
1000 llamadas al método ProjectRespository.save() para crear proyectos
2000 llamadas al método ContributorRespository.save() para crear colaboradores
2000 llamadas al método ProjectContributorRespository.save() para asociar colaboradores a proyectos
Y ni siquiera estoy contando que antes de crear un colaborador, tengo que emitir una consulta para verificar si el colaborador ya existe en la base de datos.
Todo esto está dentro de un método @Transactional. Esta lógica tarda una eternidad en completarse, me preguntaba cuál es el mejor enfoque para hacer algo como esto en Spring Boot y Spring Data para reducir significativamente la cantidad de llamadas a la base de datos para crear los objetos mencionados anteriormente.
Solución del problema
Esto suena como una buena opción para el procesamiento por lotes de inserciones. En pocas palabras, puede realizar muchas inserciones en un viaje de ida y vuelta de DB. El procesamiento por lotes es configurable por la propiedad hibernate.jdbc.batch_size
. Vale la pena señalar que el lote se dirige solo a una tabla. Entonces, 5 inserciones en la tabla Project, 5 en Contributor, luego, una vez más, 5 en Project y 5 en Contributor se realizarán en 4 lotes. Es mejor hacer 10 inserciones en Project y 10 en Contributor u ordenar las inserciones a través de la propiedad hibernate.order_inserts
. Entonces solo tiene 2 viajes de ida y vuelta de DB en el caso mencionado anteriormente. Puede leer más sobre esto en https://vladmihalcea.com/how-to-batch-insert-and-update-statements-with-hibernate/.
No hay comentarios:
Publicar un comentario