![]() |
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. |
No puedes manejar el campo de la parte como un autonumerico?
|
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. |
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. ;) |
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. |
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'; Espero te haya servido de algo. Hasta pronto :) |
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 07:28:40. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi