Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   MySQL y redes (https://www.clubdelphi.com/foros/showthread.php?t=2400)

vichovi 22-07-2003 12:45:52

MySQL y redes
 
Hola a tod@s:

Tengo el siguiente problema:

Tengo hecha una aplicación con Delphi+MySQL, la aplicación trabaja (debe trabajar) con multiples usuarios metiendo partes al mismo tiempo, el problema estriba en que el Id del parte lo genera el programa automáticamente mirando cual es el último parte y añadiendole una unidad.
Con un solo equipo metiendo partes no hay problema (sea en el puesto que sea), lo problematico es cuando dos personas estan metiendo partes desde distintos puestos y es que a las dos personas les sale el mismo número (Id) de parte, la primera que guarda el parte lo hace bien, sin embargo la segunda persona cuando le da a guardar le dice que el Id del parte ya existe.

¿Cómo podria solucionar el tema? (Creo que tendra solución, ¿¿No??:confused: )

Un saludo a todos y gracias de antemano.

__hector 22-07-2003 18:59:54

No puedes manejar el campo de la parte como un autonumerico?

Kafu 23-07-2003 09:49:54

Puedes hacer un bucle de reintentos de manera que si el último que llega no consigue grabarse porque el id estaría repetido intente obtener otro id y vuelva a grabar. No sé (imagino que sí) si MySql tiene un sistema de transacciones, en cuyo caso habría que hacer un rollback de la transacción fallida en cada reintento. Este tipo de problemas es muy común en entornos multiusuario pero si lo haces de este modo no creo que tengas pegas. Un saludo,



F.T.G.

Cabanyaler 23-07-2003 10:19:33

Vamos a ver, esto tienen su miga, yo pasé por lo mismo.

En principio, si es verdad que puedes hacerlo con un autoincrementativo, pero no soy amigo de utilizar este tipo de campos para campos claves y que además serán Claves ajenas en tablas detalle. Y por otro lado está que puede ser que el número devuelto quieras que este dentro de unos intervalos, con lo que el autoincrementativo, en este caso, no me parece demasiado amigo.

Una salida rapida es controlar si al grabar el número nuevo se produce la excepción que me comentas, capturarla y procesarla como mejor te convenga, como incrementar el numero avisando de ello, tirando atrás todo lo hecho, en fin como mejor creas conveniente, aunque esto no es lo que toca, obvio, ya que lo que debe ser es que te dé el número inmediato siguiente al último y de una manera correcta.

Para ello:

En principio, lo que yo hice es tener una tabla de intervalo exclusivamente para mantener el último número otorgado (ya sea un pedido, albarán, factura, número de cita de medico, turno en la carniceria...), con el LockType = ltOptimistic.

Cuando quiero dar de alta uno nuevo (albarán, pedido....), lo primero e inmediato que hago es una lectura de esa tabla de intervalo y retornar el valor + 1, y después incremento dicho valor en la tabla intervalo de control del último número, comprobando antes de hacer este post la existencia de (albarán, pedido....), para que no exista el número duplicado y te dé la excepción que te sale ahora.

En resumen, se busca tener siempre un número lo más actualizado posible en el tiempo, que indique el último en secuencia otorgado.

Esto lo consigues, minimizando el tiempo que transcurre desde que demandas el alta, lees el intervalo, lo incrementas, y grabas los cambios en el intervalo, agrupando en try..except o begin transacction... las operaciones de escritura en la tabla, de este modo se minimiza la posiblidad de que álguien lea e intente incrementar el intervalo al mismo tiempo.
Aún y así, si esto ocurre, y dos pc tienen retornado el mismo valor del intervalo, el intervalo no lo podrá grabar si controlas antes de hacerlo que no existe albarán o pedido con ese número, pero esto lo evitas si antes de retornar el valor del último + 1, como te digo, compruebas la existencia de algun albarán o pedido con ese número.

Bueno, sólo me queda desearte suerte, paciencia, y tiempo para hacer mil y una prueba menos una, ya que esa una que no hagas será la que se produzca en la vida real.

Nota: Ojo con el trabajo con datos en memoria y los Updatebatch, ya que estos estan en tu pc, no en el servidor ¿vale?.

Saludos.




;)

vichovi 23-07-2003 13:42:26

Primero muchas gracias a todos, intentare con la ultima de las repuestas (yo tampoco soy amigo de los autonumericos)

Ya os comentare mis progresos por si a alguien le sirve de algo...

Un saludo.

Newbie 24-07-2003 19:24:38

Heeeeeeey, he aquí lo que yo hago. Es muy simple y me ha funcionado para multiples usuarios conectados al mismo gestor:


Cuando abres un nuevo registro, tomas el max() del campo llave y le sumas 1, dando este valor al nuevo registro que estás abriendo

Cuando guardes vuelves a verificar el valor máximo por si alguien ya utilizó el que tú tenías y entonces gusrdas tu transacción con el nuevo número, dándo aviso al usuario si así lo requiere.

Código:

QFESGO.SQL.Text:='Select max(ICVe_prod) +1 as siguiente from TProducto';
Ese es el código que uso para obtener el siguiente número valido de producto. Lo asigno a mi nuevo producto y cuando termino de introducir los datos del producto vuelvo a ejecutar la consulta y me va a devolver el valor más reciente.

Espero te haya servido de algo. Hasta pronto :)

vichovi 29-07-2003 12:21:44

Gracias Newbie es la solucion que estoy utilizando :)

Un saludo y muchas gracia a todos por vuestro tiempo.


La franja horaria es GMT +2. Ahora son las 05:56:27.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi