Rafa, Me parece que el temita esta por este link...
http://msdn.microsoft.com/en-us/library/ms131281(v=SQL.100).aspx <http://msdn.microsoft.com/en-us/library/ms131281(v=SQL.100).aspx>Saludos, Pancho Cordoba El 24 de mayo de 2011 12:26, Rafael Copquin <rcopq...@ciudad.com.ar>escribió: > La conexión es la misma. No se cambia durante la transacción. Y por ahora > estoy usando ODBC, no ADO. > > Lei por ahi que al mandar el comando begin transaction via sqlexec > > sqlexec(nHandle,'BEGIN TRANSACTION') > > el ODBC pone automáticamente en MANUAL la transacción ( le manda el valor > 1 ) ¿es asi? > > Rafael Copquin > > > El 24/05/2011 9:28, Omar Bellio escribió: > > Rafa, lo que te debe estar pasando es que la conexión que usás para los > CursorAdapters es distinta a la que usa el SqlExec, por lo tanto, las > transacciones y las otras instrucciones “no están viendo el mismo canal”, > por así decirlo. > > > > La solución de Pancho, como podrás ver, usa la misma conexión ADO para toda > la operatoria entonces no tiene dramas. > > > > Otra observación, me parece que si cambiás tu bloque de instrucciones Scan > Alll… EndScan por una sola instrucción Insert into… Select… from… vas a > tener mejor rendimiento (aunque los registros sean poquitos, me parece más > elegante, pero esto es sólo una cuestión de gustos) > > > > Salute! > > > > *De:* GUFA@mug.org.ar [mailto:GUFA@mug.org.ar <GUFA@mug.org.ar>] *En > nombre de *francisco prieto > *Enviado el:* martes, 24 de mayo de 2011 08:38 a.m. > *Para:* GUFA List Member > *Asunto:* [GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones > > > > Rafa, > > > > No es que la tenga tan clara sino que me crucé con tantos quilombos en > implementaciones que decidí no utilizar cursoradapters, sino una clase > propia a la que la llame rstocursor... pero eso es harina de otro costal y > si queres en otro momento la vemos. > > > > Utilizo, gracias a esta clase ADODB y para trabajar con transacciones > simplemente hago esto: > > > > oConexionActual.Execute("SET IMPLICIT_TRANSACTIONS OFF") > > > > oConexionActual.Execute("BEGIN TRANSACTION") > > > > Luego por ejemplo hago un insert en el motor de la siguiente forma > > > > lcSql="Insert Into ColaEspera > (Orden_cEsp,F_Llegada,Nro_Turno,Estado,Flg_Espera,IdActuante,IdDerivad) > VALUES ("+; > > "'"+cOrden.Nro_Turno+"',"+; > > "'"+lcLlegada+"',"+; > > "'"+cOrden.Nro_Turno+"',"+; > > "'ES',"+; > > "'P',"+; > > "NULL"+","+; > > "'"+cOrden.IdDerivador+"')" > > Try > > > oConexionActual.Execute(lcSql) > > Catch To loError > > llHuboError=.T. > > lcTexto="La instruccion > "+Chr(13)+Chr(10)+; > > > lcSql+Chr(13)+Chr(10)+; > > "emitio el > error "+Alltrim(Str(loError.ErrorNo))+" - "+loError.Message > > > Strtofile(Transform(Date(),"@E")+" > "+Ttoc(Datetime(),2)+" "+_Screen.UsrName+" ("+; > > > ALLTRIM(_Screen.AppName)+") > "+lcTexto,_Screen.DirApp+_Screen.MisErrores.ArchLog,1) > > Endtry > > > > > > y finalmente, cuando termino con todo... > > > > If llHuboError > > oConexionActual.Execute("ROLLBACK TRANSACTION") > > Messagebox("Se produjo un error interno durante la > grabación.",16,"Avise a Sistemas") > > Else > > oConexionActual.Execute("COMMIT TRANSACTION") > > Endif > > > > Esta operatoria nunca me causo los errores que vos mencionas.... > > > > Tengo otros quilombos (quien no? :)), pero hasta el momento con SqlServer > fueron todas sonrisas... > > > > Saludos, > > > > Pancho > > Cordoba > > El 24 de mayo de 2011 08:24, Rafael Copquin <rcopq...@ciudad.com.ar> > escribió: > > Ahora yo tengo una pregunta sobre SQL Server: es el manejo de > transacciones, que es diferente de la forma en que VFP las maneja. > > > Veamos el ejemplo clásico de una factura. Dos tablas, una cabecera y otra > de detalle. > > Yo genero dos cursor adapters vacíos con este código > > local cCmd > > cCmd = [select * from cabecera where 1=0] > y genero el CA 'curCabecera' && tengo una clase que genera CA , pero es un > código largo que no viene al caso > > cCmd = [select * from detalles where 1=0] > y genero el CA 'curDetalles' > > Para hacerla corta, al grabar hago algo así > > cCmd = [begin transaction] > sqlexec(nHandle,cCmd) && con lo que le mando al SQL la orden de iniciar la > transacción > Luego > > insert into curCabecera ........ > lOK = tableupdate(.t.,.t.,'curCabecera') > if lOK > select curFactura && este es un cursor local que opera con una grilla > scan all > scatter name oFac > insert into curDetalles from name oFac > endscan > lOK = tableupdate(.t.,.t.,'curDetalles') > if lOK > cCmd = 'IF @@TRANCOUNT > 0 COMMIT' > else > cCmd = 'IF @@TRANCOUNT > 0 ROLLBACK' > endif > sqlexec(nHandle,cCmd) > > Pero sé que a esto le falta una pata, porque si provoco un error a > propósito en la grabación, para que la segunda tabla no se grabe, por > ejemplo), la segunda tabla no se graba pero la primera se graba igual. > > Intenté usar transacciones manuales antes del begin transaction > #DEFINE DB_TRANSMANUAL 2 > SQLSetProp(nHandle, "TRANSACTIONS", DB_TRANSMANUAL) > > y luego volverlas automáticas después del end transaction > #DEFINE DB_TRANSAUTO 1 > SQLSetProp(nHandle, "TRANSACTIONS", DB_TRANSAUTO) > > Pero esto hace que los cursor adapters no graben nada > > Me gustaría ver qué mecanismo usan Uds para manejar esto. A lo mejor el > hecho de que estoy usando cursor adapters cambia las cosas respecto de hacer > comandos que graben directamente en las tablas del SQL Server. Después de > todo, un CA es como una vista de VFP, con propiedades y métodos propios, > pero vista al fin. > > Pero como Pancho parece que la tiene clara, la pregunta es para vos (o > cualquier otro que también la tenga clara) > > Rafael Copquin > > > > >