Quiero poner un bloqueo de escritura en una fila de base de datos (PostgreSQL), para evitar que otra transacción (de cualquiera de los nodos) modifique la fila.
Quiero bloquear la escritura en una fila de una base de datos para no permitir que otra transacción la modifique (desde cualquiera de las pods en un entorno con clúster).
Estoy teniendo problemas en un entorno con clúster, donde tenemos 3 pods de aplicación. Intenté usar @Lock(LockModeType.PESSIMISTIC_WRITE) pero no está funcionando.
findById no bloquea la fila y devuelve la misma entidad a todas las instancias
Código de ejemplo:
“`
@Transactional
public boolean updateLicenseCount(String serviceId, String tenantId){
LicenseCountId licenseCountId = new LicenseCountId(tenantId, serviceId);
Optional<LicenseCountEntity> licenseCountEntity = springJpaLicenseCountRepository.findById(licenseCountId);</p>
<pre><code> //Realizar alguna operación en licenseCountEntity
//guardar la licenseCountEntity
}
//Esto es lo que tengo en springJpaLicenseCountRepository
@Lock(LockModeType.PESSIMISTIC_WRITE)
public Optional<LicenseCountEntity> findById(LicenseCountId licenseCountId);
</code></pre>
“`
davy.ai
Para bloquear en escritura una fila en una base de datos y evitar que otra transacción la modifique en un entorno de clúster, puedes probar el siguiente enfoque:
@Lock(LockModeType.PESSIMISTIC_WRITE)
para aplicar un bloqueo en escritura pesimista a la fila cuando la recuperes de la base de datos.@Transactional
para garantizar que la transacción se confirme después de que la fila se actualice.Sin embargo, en tu implementación actual, la anotación
@Lock
no funciona como se esperaba y el métodofindById
no bloquea la fila. Una posible razón para esto podría ser queLockModeType.PESSIMISTIC_WRITE
no sea compatible con la base de datos subyacente utilizada en el entorno de clúster.Para superar este problema, puedes intentar usar una consulta SQL personalizada para recuperar y bloquear la fila para su actualización. Aquí tienes un ejemplo:
En este ejemplo, usamos una consulta SQL nativa con la cláusula
FOR UPDATE
para bloquear la fila para su actualización. La anotación@Modifying
se usa para indicar que la consulta modifica la base de datos.Después de recuperar y bloquear la fila, puedes realizar las operaciones necesarias en la entidad y guardarla de nuevo en la base de datos.
Con este enfoque, la fila recuperada está bloqueada para su actualización y no puede ser modificada por otra transacción hasta que se libera el bloqueo.