Ver Mensaje Individual
  #4 (permalink)  
Antiguo 01/09/2011, 04:17
Avatar de Uncontroled_Duck
Uncontroled_Duck
Colaborador
 
Fecha de Ingreso: mayo-2011
Ubicación: Málaga [Spain]
Mensajes: 806
Antigüedad: 13 años
Puntos: 261
Respuesta: Bloqueo de tabla, transacciones o ambas?

Cita:
Iniciado por ocp001a Ver Mensaje
[...] y me queda el temor de que dos o más usuarios consultando al mismo tiempo el mismo saldo obtengan lecturas engañosas.

Perdón si mis preguntas resultan impertinentes, es sólo que este proyecto va a administrar grandes sumas de dinero y quiero estar completamente seguro de qué métodos debo emplear.
En absoluto me parecen impertinentes y además es normal que quieras estar seguro de que la aplicación va a funcionar perfectamente.

A ver, con la pruebas que hice ayer, planteé un caso similar pero de una única transferencia.

Lo que pude observar, es que dentro de la transacción (start / commit) puedes hacer distintas consultas con lecturas reales de la base de datos. Con esto quiero decir que si alguien cambiara algo mientras el usuario estaría operando, podrías hacer una consulta antes de y otra después de...

Pongo como ejemplo el caso que has sugerido.

Código PHP:
Ver original
  1. 0.001 ms:
  2.     Usuario A necesita $100, consulta si hay disponibilidad,
  3.     y sí, hay $150 disponibles.
  4.  
  5. 0.002 ms:
  6.     Usuario B necesita $80, consulta si hay disponibilidad,
  7.     y sí, (todavía hay $150 disponibles).
  8.  
  9. 0.003 ms:
  10.     //Usuario A actualiza y resta sus $100, ahora quedan $50 disponibles
  11.     Usuario A resta sus $100, ahora quedan $50 disponibles
  12.     ---- Antes de confirmar la transacción
  13.     Consultas si ahora esta la cantidad esperada $50
  14.     Si es la esperada COMMIT;
  15.     Si no es la esperada ROOLBACK; y notificas que hay un cambio.
  16.  
  17. 0.004 ms:
  18.     Usuario B acaba de consultar que quedan $150,
  19.     //así que actualiza y resta $80,
  20.     ---- Antes de confirmar la transacción
  21.     Consultas si ahora esta la cantidad esperada $70
  22.     Si es la esperada COMMIT;
  23.     Si no es la esperada ROOLBACK; y notificas que hay un cambio.
  24.     //pero como sólo quedaron $50, resulta en un -30 (y por tanto un fallo).

Sabemos que nuestra transacción no se hace visible al resto de usuarios hasta que no ejecutemos el COMMIT, pero dentro de la misma transacción si podemos hacer lecturas reales de las cantidades que hay en la DB (incluida nuestra transacción).

Si mientras tenemos abierta la transacción, alguien completa otra, nos aparecerá ese cambio inesperado en la consulta que haremos justo antes de confirmar dicha transacción. Lo cual nos da la oportunidad de actuar en consecuencia.

Todo esto se deduce a raíz de la documentación de MySql, libros que tengo al respecto y pruebas que he realizado con PHPUnit. Pero para verificar toda esta teoría no hay nada mejor que realizar las pruebas por ti mismo, con los casos que estimes oportunos.

PD.: Con PHPUnit puedes hacer este tipo de pruebas y ver como y donde falla la aplicación según el comportamiento que buscas.

Saludos,
__________________
Todos agradeceremos que pongas el código en su respectivo Highlight