From: | Edwin Quijada <listas_quijada(at)hotmail(dot)com> |
---|---|
To: | "Ing(dot) Eris J(dot) Gomez" <eris_jose(at)hotmail(dot)com>, <pgsql-es-ayuda(at)postgresql(dot)org> |
Subject: | RE: Transacciones en PG |
Date: | 2008-04-30 19:48:42 |
Message-ID: | BLU137-W5352CF50A072987DCAE22BE3D80@phx.gbl |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-es-ayuda |
Como te dijo Alvaro eso esta todo malo.
Si no te gusta el campo serial otra forma seria:
una tabla de secuencias con tipo de docuemntos y bloquea esa tabla al momento de pedir la secuencia seria algo asi
Pseudocodigo
CREATE FUNCION secuecnia(varchar tipo) as Intreger Return
$$body$$
LOCK TABLE(seceucnia)
select into se sec+1 from secuecnia where tipo=$1;
if (found)
update secuencia set sec=se where tipo=$1;
return(se);
else
insert into secuecnia values($1,1);
return(1);
end if;
Seria algo asi. Eso lo he usado toda mi vida con excelentes resultados. La tabla se desbloquea sola al terminar la transaccion.
*-------------------------------------------------------*
*-Edwin Quijada
*-Developer DataBase
*-JQ Microsistemas
*-809-849-8087
* " Si deseas lograr cosas excepcionales debes de hacer cosas fuera de lo comun"
*-------------------------------------------------------*
________________________________
From: eris_jose(at)hotmail(dot)com
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: [pgsql-es-ayuda] Transacciones en PG
Date: Wed, 30 Apr 2008 11:47:34 -0400
Gracias por su ayuda. A continuación les envío
parte del código que realiza una transacción minima.
Tengo esta funcion en PostgreSql:
Función
PlpGSql
-----------------------------------------
CREATE OR REPLACE FUNCTION
"public"."generar_secuencia" (_compania varchar, tabla varchar, tipdoc varchar,
origen char, actualizar integer) RETURNS integer AS
DECLARE
cantidad integer;
secue_sec2
varchar(15);
tipdoc_sec2
varchar(15);
origen_sec2
varchar(15);
campocia_sec2
varchar(15);
cont
integer;
secuencia integer;
cur
record;
BEGIN
--insertando el registro
en caso de que no exista
select into cantidad
count(*) from clasecue where codcia_sec=_compania
and nomtab_sec=tabla and tipdoc_sec=tipdoc and origen_sec=origen;
if cantidad=0 --si en la
tabla de secuencias no existe un registro para la tabla especificada, con el
tipo de documento especificado
then
--consultando los nombres de los campos
que voy a buscar en la tabla para generar la secuencia
select into
secue_sec2,tipdoc_sec2,origen_sec2,campocia_sec2,cont
secue_sec,tipdoc_sec,origen_sec,campocia_sec,count(*)
from claconse where
nomtab_sec=tabla
group by
secue_sec,tipdoc_sec,origen_sec,campocia_sec;
if cont>0 --si
la tabla claconse tiene tiene informacion sobre la tabla a la que se le va a
generar la secuencia, busco la secuenca actual de esa
tabla-
then
--buscando la ultima secuencia de
la
tabla
if origen_sec2>'' --si la tabla maneja origen
then
for cur in execute 'select max('||secue_sec||')as secuencia from
'
||tabla||' where
'||campocia_sec||'='''||_compania||''' and
'||tipdoc_sec||'='''||tipdoc
||''' and
'||origen_sec||'='''||origen||''''
loop
secuencia=cur.secuencia;
end loop;
else
for cur in execute 'select
max('||secue_sec||')as secuencia from '||tabla||' where
'||campocia_sec||'='''
||_compania||''' and
'||tipdoc_sec||'='''||tipdoc||''''
loop
secuencia=cur.secuencia;
end
loop;
end
if;
if secuencia is
null
then
secuencia=0;
end if;
else --de la contrario,
devuelvo secuencia 0 ya que no tengo suficiente informacion para generar la
secuencia
secuencia=0;
end
if;
--se inserta
en la tabla de secuencias un registro para la tabla y el tipo de documento
especificado
insert into clasecue
(codcia_sec,nomtab_sec,tipdoc_sec,origen_sec,numdoc_sec)
values (_compania,tabla,tipdoc,origen,secuencia);
end
if;
-------------------------------------------------------------------------------
if
actualizar=1
then
--actualizando la secuencia de la
tabla especificada
update clasecue set
numdoc_sec=numdoc_sec+1 where codcia_sec=_compania and
nomtab_sec=tabla
and
tipdoc_sec=tipdoc and origen_sec=origen;
end
if;
--buscando la
secuencia generada para que la aplicacion que llame esta funcion, la
tome
select into secuencia numdoc_sec+1 from
clasecue where codcia_sec=_compania and
nomtab_sec=tabla and tipdoc_sec=tipdoc and origen_sec=origen;
return
secuencia;
END;
Ahora bien:
En el frontend ejecuto el
siguiente codigo:
Transaccion(1) // Esto me
inicia una transaccion en PostgreSql
camposecuencia = invocar_secuencia_PG(parametros)
Inserto los datos del header
inserto los datos del detalle
Transaccion(3) //Commit de la
transaccion
Ya me ocurrio que varios usuarios casi al mismo
tiempo ejecutaron el proceso y se perdio una secuencia.
Creen que haya algo malo en esta funcion?
Gracias nuevamente.
_________________________________________________________________
Stop squinting -- view your photos on your TV. Learn more.
http://www.microsoft.com/windows/digitallife/default.mspx?deepLink=photos
From | Date | Subject | |
---|---|---|---|
Next Message | Fernando Moreno | 2008-04-30 20:27:51 | return query sobre esquemas cambiantes |
Previous Message | Martin Marques | 2008-04-30 18:35:10 | Re: Error 'Could not open file "pg_clog/00A1"' al hacer SELECT a una tabla x |