Es muy común que los programadores quieran tener en una columna el saldo actualizado de ese ítem, pero … ¿es eso conveniente?

Supongamos que tenemos una tabla de PRODUCTOS con las columnas:

  • Identificador del producto
  • Código del producto
  • Nombre del producto
  • Cantidad inicial
  • Cantidad actual

Luego, cada vez que entra o sale un producto del stock se actualiza la columna “Cantidad actual” para así tener siempre a mano cual es la cantidad actual de dicho producto.

¿Es ésa una buena práctica?

No.

¿Por qué no?

Porque cada vez que una transacción actualiza una columna se bloquea la fila completa. La primera transacción que intente hacerlo no tendrá problemas pero las siguientes sí, porque la fila que quieren actualizar está bloqueada. Y en ese caso solamente tienen dos alternativas:

  1. Esperar que la transacción que tiene bloqueada a una fila la desbloquee
  2. Abandonar el intento de actualización con un mensaje de error

Y ninguna de esas alternativas es aceptable en un entorno donde hay mucha concurrencia (o sea, muchas computadoras queriendo actualizar el mismo ítem)

Ejemplo del problema que puede ocurrir:

Un supermercado tiene 25 cajas, es fin de año, época de muchas ventas. La caja 1 registra un producto, actualizando su cantidad en stock. Las cajas 7 y 18 quisieron actualizar también la cantidad en stock de ese producto y fueron rechazadas. La caja 1 liberó al producto, el cual ahora fue actualizado por la caja 7 pero la caja 18 continúa esperando. La caja 1 registra otro producto, y al hacerlo lo bloquea. Las cajas 12, 14, y 20 que querían también registrar ese producto no pueden hacerlo. La caja 3 bloqueó a otro producto, que la caja 5 también debe actualizar y por lo tanto no puede.

Puede ser un problema interminable porque cuando una caja libera a un producto otra caja lo bloquea.

Por lo tanto, querer tener actualizada la cantidad en stock de un producto que puede ser vendido desde muchas computadoras y al mismo tiempo, es un gran error.

A la gente no le gusta esperar, si tienen que estar esperando y esperando y esperando hasta que cada producto pueda ser registrado en la caja lo más probable es que se vayan y no vuelvan. Y si se van se pierden clientes, y si se pierden clientes se pierden ventas, y si se pierden ventas se pierde dinero. Y si pierden dinero, lo más probable es que los dueños de la empresa se deshagan rápidamente del programa inútil y del programador inútil, y contraten algo que realmente les sirva.

¿En qué casos sí se puede actualizar el saldo en línea?

Cuando la probabilidad de que el ítem sea accedido para actualización desde 2 ó más computadoras es cero o casi cero. Por ejemplo, en el momento en que se le vende a un cliente o se le cobra a un cliente sí es correcto actualizar su saldo. ¿Por qué? Porque es altamente improbable o imposible que al mismo cliente se le esté vendiendo o cobrando desde dos o más computadoras. Si el cliente está en la caja 5 pues está en la caja 5, no está también en la caja 12 y en la caja 18. Por lo tanto, es imposible que haya conflicto cuando se quiere actualizar su saldo.

Lo mismo sucedería con los proveedores. Es muy raro que un proveedor entregue varias facturas y esas facturas sean cargadas al mismo tiempo y en distintas computadoras; entonces actualizar su saldo cada vez que se carga una factura es correcto.

Algo similar sucede con los alumnos y las cobranzas de las cuotas. Es prácticamente imposible que al mismo alumno se le esté cobrando al mismo tiempo desde dos o más computadoras.

¿Cómo se obtiene el saldo actual si no se lo actualiza en línea?

Como vimos, en el caso de los productos de un supermercado sería un error querer tener actualizados los saldos de los productos en línea (o sea, en el mismo momento en que se venden). Pero los usuarios necesitan conocer ese saldo, ¿cómo lo solucionamos?

Hay dos alternativas:

  1. Si la velocidad con la cual se recuperan los datos de la consulta es alta, un simple SELECT será suficiente. A la cantidad inicial del producto (que tenemos guardada en la tabla PRODUCTOS) se le suman todas las entradas y se le restan todas las salidas, hallándose así la cantidad actual.
  2. Si realizar la consulta especificada en el punto 1. demora mucho, entonces se tiene una tabla de SALDOS que son actualizados periódicamente (una vez al día, una vez a la semana, una vez al mes, etc.) y luego a la cantidad que hay en esa tabla de SALDOS se le suman las entradas y se le restan las salidas. Por ejemplo, si la tabla de SALDOS se actualiza diariamente (por ejemplo: al final de la jornada laboral), para saber la cantidad actual de un producto se obtiene la cantidad que tenía ayer (ese dato está en la tabla de SALDOS) y se le suman todas las entradas y se le restan todas las salidas que ocurrieron el día de hoy.

Conclusión:

Cuando un ítem (por ejemplo: un producto) puede tener mucha concurrencia (o sea, que accedan a sus datos para modificarlos desde varias computadoras y al mismo tiempo) no se debe actualizar el saldo de ese ítem porque si se lo actualiza solamente acarreará problemas a los usuarios.

Cuando un ítem (por ejemplo: un proveedor) tiene baja concurrencia entonces sí es correcto actualizar su saldo.

La pregunta que debemos hacernos es: ¿es probable que al mismo tiempo se quiera actualizar el saldo de este ítem desde 2 ó más computadoras? Si la respuesta es afirmativa entonces no debemos actualizar el saldo.

Artículos relacionados:

Modos de bloqueo de las transacciones

Bloques mortales

El índice del blog Firebird21

Anuncios