![]() |
Bloqueo de tablas en MS Sql Server
Buenos Dias...
tengo una inquietud que me gustaria compartir con ustedes y aprovechar sus comentarios En Visual FOX yo podia bloquear una tabla (DBF) con el comando Flock('Tabla'), esto hacia que cuando algun usuario queria utilizar el sistema.. por la tabla bloqueada, el sistema se mantenia "en espera" (Mientras se actualizaba informacion), hasta que la tabla fuera liberada (UNLOCK) Al tener la tabla Bloqueada, se podia grabar con mas precision los datos, sobre todo el numero de documento correlativo (ya uds. entienden la problematica) Normalmente, tenia una tabla Vacia, a la cual se le efectuaba el bloqueo, hacia esto para no tener que bloquear las tablas de movimientos que mantenian mucha informacion Ya no Uso Visual FOX, Uso Delphi, ya no Uso DBF uso MS Sql Server, me gustaria saber si el procedimiento es el mismo, o Solo Bloquea la Tabla en cuestion para su imposible actualizacion de datos gracias por los comentarios |
Tengo entendido que sí es el mismo proceso, pero ¿para que usar "bloqueos" cuando puedes manejar "Transacciones"?
saludos. |
y podrias explicarme un poco el tema de transacciones por favor...
|
Te dejo algunas notas de Microsoft SQL SERVER 2005
Código:
Marca el punto de inicio de una transacción local explícita. La instrucción BEGIN TRANSACTION incrementa @@TRANCOUNT en 1. |
El bloque de tablas no es aplicable (o no debería serlo) a SGBD como SQL Server (justo va en contra de la idea de un SGBD).
La alternativa, tal y como han comentado, son las transacciones. Utilizándolas puedes conseguir que una operación o varias se realicen de forma individual. Con eso se suele solventar el problema que comentas de los números correlativos; Es bastante habitual, por ejemplo, en el tema de facturación. Revisa la ayuda de SQL Server y de ADO sobre "Isolation Level"; Para las transacciones y dependiendo de lo que quieras hacer pueder definir un nivel diferente o una forma diferente de trabajar. Si buscas en los foros, también encontrarás hilos al respecto, puesd ya hemos hablado otras veces de estos temas. |
encontre este ejemplo en una web, me gustaria saber sus comentarios
|
Bueno, más o menos es la forma estandard de hacer las cosas desde Delphi.
(1) Abres la transacción (2) Ejecutas las operaciones que quieres que se hagan TODAS como una unidad (3) Si ha ido todo bien, realizas el COMMIT (que acepta TODOS los cambios) (4) Si ha ocurrido algun error, realizas un COMMIT que deshace TODOS los cambios.
|
pues eso es básicamente lo que tendrías que hacer. Solamente la variable "Level" es opcional en caso de vayas a manejar varias transacciones anidadas y quieres llevar el control de cada trasancacción, si no quieres llevar el control específico por cada transacción, pues no sería necesaria esa variable.
Como "cuestión de estilos" a mi no me gusta usar la excepción general "E:Exception", prefiero usar la clase específica para darle un manejo específico a cada tipo de error. Y Finalmente, en el bloque de código que pones, en caso de ocurrir un error, se hace el "rollback", pero no se muestra ningún mensaje por lo que el usuario nunca se enteraría del error. tendría que ser algo como:
Importante: el mensaje debe de ir siempre después del "rollback", si lo pones antes, el "rollback" se ejecutará hasta después de que le den "aceptar" y está científicamente comprobado que si el usuario se está tomando un café (o apenas fue a hacerlo) se va a tardar mucho en darle aceptar y la base de datos se queda bloqueada por que la transacción no termina. |
Perfecto !!!!
|
retomando este tema
se me ha presentado un problema tengo una tabla que esta en constante actualización, el asunto es que tengo que agregar nuevos registros a esta tabla hay un campo que se llama formulario, lo obtengo generando el MAX del campo y le sumo 1, el asunto es que cuando estoy tratando de obtener el ultimo numero para sumarle uno, alguien mas en la web (php) que usa esta misma tabla ya capturo y grabo ese numero, por lo cual me aparece el mensaje de error (porque es un campo PK) que no acepta duplicados uso transacciones
el tema es que ahora estoy usando Firedac que estoy haciendo mal ? no podria bloquear la tabla para grabar el registro q quiero y despues liberarla ? o estoy usando mal las transaciones |
La primera opción sería usar un campo AutoIncremental, si es que lo tienes disponible, con eso evitas trabajo (buscar el máximo y sumar 1) y evitas problemas.
Si no puedes usar Autoincrementales, debes hacer ambas operaciones dento de la misma transacción. Si es necesario, modificas el IsolationLevel de la transacción y con eso deberías eviar duplicados. Aunque como he comentado, no es la práctica recomendable en SGBD's bloquear tablas. Las transacciones son para otros menesteres. |
Cita:
Esta es la clave. Cita:
https://stackoverflow.com/questions/...y-alternatives Como funciona un max? Tienes un MILLON de registros. La BD por defecto, recorre el MILLON de registro comparando si este es mayor al anterior. Al final, da un resultado. Luego le sumas 1. Esos significa que estas introduciendo una ESPERA. Eso genera una ventana para que otra operacion compita contigo. (Con un indice se puede agilizar el proceso. Igual, es una demora) En otras palabras, el orden de ejecucion en una RDBMS NO ES deterministico, sino aleatorio. (a menos que uses una transaccion, pero nota mas abajo). La forma de tener tu propio generador:
Cita:
Cita:
----- Asi, que que hacer? El problema que tienes te grita: Tu diseño esta errado. Deja que la BD genere IDs. A menos que presentes un escenario justificable, yo pararía ahi. |
La franja horaria es GMT +2. Ahora son las 08:02:28. |
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