En mi solicitud rieles, tengo algo de código como este:¿Cómo puedo bloquear un conjunto de objetos para una operación?
def foo
if object_bar_exists
raise "can't create bar twice!"
end
Bar.create
end
que podría ser invocada por dos solicitudes diferentes que entran en el servidor de aplicaciones. Si este código es ejecutado por dos solicitudes al mismo tiempo, y ambas ejecutan la verificación if
al mismo tiempo, ninguna de las dos encontrará bar
, y se crearán 2 bar
s.
¿Cuál es la mejor manera de crear un "mutex" para "la colección de barras"? ¿Una tabla mutex de propósito especial en DB?
actualización
Debo hacer hincapié en que no puedo utilizar un mutex de memoria aquí, debido a que la concurrencia es a través de las peticiones/procesos y no hilos.
Pensé que las transacciones solo aseguran que todo lo que está dentro de ellas se realiza atómicamente. ¿No puede el mismo código de uso de transacciones ser ejecutado por dos procesos en paralelo y tener los mismos problemas? (Las verificaciones iniciales de 'si' se ejecutan en paralelo y se ejecutan correctamente, y luego las escrituras ocurren en paralelo, y en ambos casos, todos los códigos respectivos ocurren atómicamente) –
No si bloquea la fila. Es el nivel de fila bloqueado en el DB, por lo que otra transacción no puede acceder a él.Además, si tiene errores de validación que garantizan una fila única, la primera escritura tendrá éxito y la siguiente fallará y revertirá la transacción completa. –
Realmente desea la transacción ** y ** un índice único dentro de la base de datos para forzar el problema. La transacción mantendrá todo limpio cuando las cosas van mal, el índice único le dirá cuando las cosas van mal. –