Hola a todos:
Estamos migrando una aplicacion para que trabaje contra un servidor SLQ
Server 2005. La duda es sobre el nivel de aislamiento de las transacciones.
Lo explico con un ejemplo. En la aplicacion gestiona clientes, cada uno
logicamente tiene su codigo de cliente (por ejemplo un campo numerico). Lo
que queremos es que al crear un nuevo cliente se busque el ultimo codigo de
cliente, le sumamos 1 y añadimos el nuevo cliente.
El problema viene cuando se trabaja en multiusuario. Tenemos que evitar que
se creen 2 codigos de cliente iguales.
Para ejemplificarlo, en lugar de poner nuestro codigo en C++, os pongo el
siguiente 'pseudocodigo':
use BASEDEDATOS
set transaction isolation level serializable
begin transaction
// Punto 1: Obtenemos el ultimo registro
select top(1) codigo from clientes order by codigo desc
nuevocodigo = clientes.codigo+1
// Punto 2: Grabamos
insert into clientes (codigo) values(Nuevocodigo)
commit
En el pseudocodigo anterior, si 2 procesos se ejecutan simultaneamente,
ambos ejecutan el Punto1 a la vez... los 2 procesos dan con el mismo codigo,
duplicando el codigo de articulo.
He probado con todos los niveles de aislamiento: READ COMMITTED, UNCOMMITED,
SERIALIZABLE, REPEATABLE READS, SNAPSHOT, pero en todos falla.
Supongo que esto debe hacerse mejor de otra forma (hacer el codigo como
campo identity por ejemplo), pero no me sirve, ya que como os he comentado
estamos migrando una aplicacion (programada al estilo XBase) y es una
aplicacion bastante grande, lo tengo todo migrado a excepcion de este
problema y no es solo al crear un cliente, sino en muhos otros puntos del
programa.
Gracias por adelantado.
Saludos,
Vicente Flich
Flifeca Aplicaciones Informáticas
Leer las respuestas