tenemos algunos datos persistentes en una aplicación, que se consulta desde un servidor y luego se almacena en una base de datos para que podamos seguir la pista de información adicional. Como no queremos consultar cuando se usa un objeto en la memoria, hacemos un select for update
para que otros hilos que quieran obtener los mismos datos sean bloqueados.Tiene el bloque "seleccionar para actualizar" en filas no existentes
No estoy seguro de cómo select for update
maneja las filas que no existen. Si la fila no existe y otro subproceso intenta hacer otra select for update
en la misma fila, ¿se bloqueará este subproceso hasta que la otra transacción finalice o también obtendrá un conjunto de resultados vacío? Si solo obtiene un conjunto de resultados vacío, ¿hay alguna forma de bloquearlo también, por ejemplo, insertando la fila que falta inmediatamente?
EDIT:
Debido a que hubo una observación, que puede producir un bloqueo tanto, he aquí algunos detalles más sobre el uso de concreto en nuestro caso. En pseudocódigo reducida nuestro flujo Programm se ve así:
d = queue.fetch();
r = SELECT * FROM table WHERE key = d.key() FOR UPDATE;
if r.empty() then
r = get_data_from_somewhere_else();
new_r = process_stuff(r);
if Data was present then
update row to new_r
else
insert new_r
Este código se ejecuta en múltiples hilos y los datos que se obtiene de la cola podría estar en relación con la misma fila en la base de datos (de ahí el bloqueo). Sin embargo, si varios hilos están usando datos que necesitan la misma fila, entonces estos hilos deben ser secuenciados (el orden no importa). Sin embargo, esta secuenciación falla, si la fila no está presente, porque no obtenemos un bloqueo.
EDIT:
Por ahora tengo la siguiente solución, que parece un truco feo para mí.
select the data for update
if zero rows match then
insert some dummy data // this will block if multiple transactions try to insert
if insertion failed then
// somebody beat us at the race
select the data for update
do processing
if data was changed then
update the old or dummy data
else
rollback the whole transaction
No estoy ni 100% seguro de que esto realmente resuelva el problema, ni esta solución parece un buen estilo. Entonces, si alguien tiene que ofrecer algo más utilizable, sería genial.
En relación con su edición: ¿Dónde obtiene un candado? –
@Catcall: Ups, olvidé "PARA ACTUALIZAR" en la instrucción de selección. Entonces este es el lugar donde se toma la cerradura. – LiKao