2010-08-17 12 views
5

Buscando un consejo de mejores prácticas:Bloqueo selectivo en rieles con MySQL

Supongamos que tengo un objeto Cuenta con atributo de límite. Cada día puede haber n pagos, con la suma de sus cantidades hasta el límite de la cuenta. Al crear un nuevo pago, verifica si el importe + los montos de otros pagos del día aún se encuentran dentro del límite de la cuenta y guarda el registro o muestra un error.

Supongamos ahora que tengo una cuenta con un límite de 100 $ y, al mismo tiempo, se están creando dos pagos de 99 $. Cada uno haría una selección, vería que no hay nada allí y procedería a guardarse a sí mismo, lo que resultaría en un ahorro de $ 198.

¿Qué harías al respecto? Estaba pensando en emitir un bloqueo de escritura en la tabla de pagos al inicio de la transacción, pero parece ser bastante torpe, ya que realmente solo me importa no permitir que los pagos pertenecientes a una cuenta específica no sean leídos por otras transacciones. ¿Hay alguna otra opción, mejores formas de manejar esta situación?

Respuesta

3

Estaba pensando en la emisión de un bloqueo de escritura en la tabla de pagos en el inicio de la transacción, pero que parece quit eheavy sola mano

Suponiendo que ya está hablando de transacciones, supongo que no está utilizando MyISAM, pero en su lugar InnoDB o algún otro motor que ya admite transacciones.

El bloqueo de transacciones de lectura o escritura para conservar la atomicidad de las operaciones no es algo que deba hacerse manualmente. Es el trabajo del nivel de aislamiento de su transacción hacer eso. Esto también preservará la atomicidad de las operaciones entre la apertura de la transacción y el bloqueo de su tabla o registros, para que no se filtre nada mientras tanto.

Para el caso de uso que describa, lo que quiere son transacciones con el nivel de aislamiento 'SERIALIZABLE', que se bloqueará para lectura y escritura. Además, bloqueará automáticamente solo los registros "desde los que ha leído" (incluso si consulta por rangos), por lo tanto, dejará los registros restantes libres para su manipulación.

A través del nivel de aislamiento 'SERIALIZABLE', en el momento que lea la información de la tabla, cualquier intento de actualizar o leer esos registros tendrá que esperar hasta que la transacción finalice. Además, asegúrese de leer antes de actualizar en la misma transacción, por lo que seguramente trabajará con el valor correcto.

Puede leer más acerca de los niveles de aislamiento aquí: http://en.wikipedia.org/wiki/Isolation_(database_systems) http://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm

Usted puede aprender cómo configurar el nivel de aislamiento de las transacciones aquí: http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html

+0

"el momento en que leen la información de la tabla , cualquier intento de actualizar o leer esos registros tendrá que esperar hasta esa transacción "- ¿y si aparece el selecto sin registros? o en el caso del preguntador, está consultando el valor agregado de los registros existentes antes de agregar nuevos. ¿cómo sabe mysql qué bloquear? –

Cuestiones relacionadas