Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search archives
  Advanced Search

RE: Transacciones en PG


  • From: Edwin Quijada <listas_quijada(at)hotmail(dot)com>
  • To: "Ing. Eris J. Gomez" <eris_jose(at)hotmail(dot)com>, <pgsql-es-ayuda(at)postgresql(dot)org>
  • Subject: RE: Transacciones en PG
  • Date: Wed, 30 Apr 2008 19:48:42 +0000
  • Message-id: <BLU137-W5352CF50A072987DCAE22BE3D80@phx.gbl> <text/plain>

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


Home | Main Index | Thread Index

Privacy Policy | About PostgreSQL
Copyright © 1996 – 2012 PostgreSQL Global Development Group