2009-11-21 17 views
6

Me gustaría crear una interfaz para manipular facturas de una manera similar a la transacción.Transacción MySQL en muchas solicitudes PHP

La base de datos consta de una tabla de facturas, que contiene información de facturación, y una tabla de líneas de factura, que contiene líneas de pedido para las facturas. El sitio web es un conjunto de scripts que permiten la adición, modificación y eliminación de facturas y sus líneas correspondientes.

El problema que tengo es esto, me gustaría que las propiedades ACID de la base de datos se vean reflejadas en la aplicación web.

  • Atómica: Cuando el usuario pulsa guardar, ya sea toda la factura se modifica o toda la factura no se cambia en absoluto.
  • consistente: el código de la aplicación ya garantiza la coherencia, las líneas no se pueden agregar a las facturas inexistentes. Los ID de factura no se pueden duplicar.
  • Aislado: Si un usuario está en medio de un conjunto de cambios en una factura, me gustaría ocultar esos cambios a otros usuarios hasta que el usuario haga clic en guardar.
  • Durable: Si el sitio web muere, los datos deberían ser seguros. Esto ya funciona

Si estuviera escribiendo una aplicación de escritorio, sería mantener una conexión a la base de datos MySQL en todo momento, lo que me permite usar simplemente el BEGIN TRANSACTION y COMMIT al principio y al final de la edición.

Por lo que entiendo, no puede COMENZAR TRANSACCIÓN en una página de PHP y COMPROMETER en una página diferente porque la conexión se cierra entre páginas.

¿Hay alguna manera de hacer esto posible sin extensiones? Por lo que he encontrado, solo SQL Relay hace esto (pero es una extensión).

Respuesta

1

La solución no es abrir la transacción durante la fase GET. Realice todos los aspectos de la transacción: BEGIN TRANSACTION, processing y COMMIT-all durante la POST activada por el botón "guardar".

+0

El problema con esta idea es que otro usuario podría editar los datos debajo de mí. Esto requiere un código adicional para rastrear los cambios en cada factura (es decir, número de revisión). Las transacciones nativas simplemente arrojarían un conflicto de compromiso y mi aplicación podría volver a lanzar eso al usuario. – Martin

+1

@Martin: para solucionar los problemas de simultaneidad, agregue una columna de versión a la (s) tabla (s) para que un registro no se pueda actualizar/eliminar a menos que los valores de la versión coincidan entre lo que el usuario está editando actualmente y lo que el db almacena actualmente. –

+1

En ese caso, debe crear un mecanismo de bloqueo pesimista u optimista para evitar que otro usuario lo haga. Pesimista al "bloquear" a otros usuarios basándose en una clave de una parte de la jerarquía en la que desea bloquear, u optimista (suponiendo que esto no ocurra a menudo) pidiéndoles que vuelvan a ingresar sus datos. –

2

Las transacciones de la base de datos en realidad no están pensadas para este propósito; si las usa, probablemente se encuentre con otros problemas.

Pero tampoco puede usarlos ya que cada solicitud de página usa su propia conexión (potencialmente) por lo que no puede compartir una transacción con ninguna otra.

Guarde las modificaciones en la factura en otro lugar mientras el usuario las está editando, y luego las aplica cuando toca guardar; puede hacer este paso de aplicación final en una transacción (aunque bastante corta).

Las transacciones de larga duración suelen ser malas.

0

conexiones persistentes pueden ayudarle a: http://php.net/manual/en/features.persistent-connections.php

Otra es que cuando se utiliza transacciones, un bloque de transacción también llevan a la siguiente secuencia de comandos usando la conexión, si la ejecución del script termina antes de la transacción bloque hace.

Pero le recomiendo que busque otro enfoque al problema. Por ejemplo: cree una tabla de caché. Cuando necesite "confirmar", transfiera los registros de la tabla de caché a las tablas "reales".

4

La traducción en la web para este tipo de procesamiento es el uso de datos de sesión o datos almacenados en la página. Normalmente, una vez que se completa cada página web, los datos se almacenan en la sesión (o en la página) y en el punto en el que se han completado todas las páginas (mediante el ingreso de datos) y un "Proceso" (o el botón "Guardar"), los datos se convierten a la base de datos y se guardan, incluso con el aspecto relacional de los datos como usted mencionó. Hay muchas maneras de hacerlo, pero diría que la mayoría de los desarrolladores tienen una arquitectura similar a la que mencioné (usando datos de sesión o estado dentro de la página) para satisfacer lo que usted está hablando.

Usted obtendrá muchos consejos aquí en diferentes arquitecturas, pero puedo decir que el Zend Framework (http://framework.zend.com) y el uso de la Doctrina (http://www.doctrine-project.org/) hacen que esta hada fácil, ya que Zend proporciona gran parte de la arquitectura y MVC sesión de gestión y Doctrina proporciona el CRUD básico (crear, recuperar, actualizar, eliminar) que está buscando, además de todos los demás aspectos (unicidad, confirmación, retrotracción, etc.). Mantener la conexión abierta a mysql puede causar tiempos de espera y la falta de conexiones disponibles.

0

Aunque hay algunas buenas respuestas, creo que encontré algunas buenas respuestas a su pregunta, con las que también me quedé. Creo que el mejor enfoque es utilizar un marco como Doctrine (mapeo O/R) que tiene este tipo de enfoque implementado de alguna manera. Here tiene un enlace de lo que estoy hablando.

Cuestiones relacionadas