BEGIN TRANSACTION UPDATE Table1 SET MyField = 'MyValue' WHERE AnotherField = Somevalue UPDATE Table2 SET MyField = 'MyValue' WHERE AnotherField = Somevalue UPDATE Table3 SET MyField = 'MyValue' WHERE AnotherField = Somevalue COMMIT TRANAnd it is nicely wrapped in a transaction and it either all succeeds or fails.
BEGIN TRANSACTION UPDATE View1 SET MyField = 'MyValue' WHERE AnotherField = Somevalue UPDATE View2 SET MyField = 'MyValue' WHERE AnotherField = Somevalue UPDATE View3 SET MyField = 'MyValue' WHERE AnotherField = Somevalue IF TABLEUPDATE(2, .T., "View1") AND TABLEUPDATE(2, .T., "View1") AND TABLEUPDATE(3, .T., "View1") END TRANSACTION ELSE ROLLBACK ENDIFWhen adding SQL server transactions you have to deal with the VFP transaction and SQL transaction simultaneously. And that is a bit tricky. You could end up having the VFP transaction rolled back and the SQL server transaction committed or visa versa.
LOCAL oTx oTx = CREATEOBJECT("Transactionhandler") oTx.Start() UPDATE View1 SET MyField = 'MyValue' WHERE AnotherField = Somevalue UPDATE View2 SET MyField = 'MyValue' WHERE AnotherField = Somevalue UPDATE View3 SET MyField = 'MyValue' WHERE AnotherField = Somevalue IF TABLEUPDATE(2, .T., "View1") AND TABLEUPDATE(2, .T., "View2") AND TABLEUPDATE(3, .T., "View3") AND oTx.Commit() ** Success ELSE ** Failed oTx.Rollback() ENDIFIt is not that complicated, but it very easy to make mistakes. For example handling errors that might occur during the transaction) in which the transaction might erroneously be committed rather than rolled back.
DEFINE CLASS TransactionHandler AS CUSTOM *[2008/05/28 15:16:53] WM. A class that handles transactions. *[2010/07/29 10:17:20] Major revision DIMENSION Errors[1,7] DATASESSION = 1 DBConnection = NULL FUNCTION INIT(oDbConn) DO CASE CASE TYPE("oDbConn.DataSourceType") = "C" ** UDF connection THIS.DBConnection = oDbConn CASE TYPE("oDbConnection.DataSourceType") = "C" ** Application wide connection THIS.DBConnection = oDBConnection OTHERWISE ** Native connection only THIS.DBConnection = CREATEOBJECT("DBConnection") THIS.DBConnection.CONNECT() ENDCASE ENDFUNC *- FUNCTION START() =ExplicitPurgeMemory() && SYS(1104) to clean buffer to prevent C5 STORE .F. TO THIS.Errors BEGIN TRANSACTION IF THIS.DBConnection.DATASOURCETYPE = "ODBC" SQLSETPROP(THIS.DBConnection.Sqlhandle,"transActions",2) && Manual Transaction ENDIF ENDFUNC *- FUNCTION Commit() LOCAL lRet lRet = .T. DO CASE CASE THIS.DBConnection.DATASOURCETYPE = "ODBC" AND SQLCOMMIT(THIS.DBConnection.Sqlhandle) > 0 ** Succesfull END TRANSACTION SQLSETPROP(THIS.DBConnection.Sqlhandle,"transActions",1) && Automatic Transaction CASE THIS.DBConnection.DATASOURCETYPE = "ODBC" ** Remote save not succesfull TRY AERROR(THIS.Errors) CATCH ENDTRY THIS.ROLLBACK() lRet = .F. OTHERWISE ** VFP tables END TRANSACTION FLUSH ENDCASE RETURN lRet ENDFUNC *- FUNCTION ROLLBACK DO CASE CASE THIS.DBConnection.DATASOURCETYPE = "ODBC" SQLROLLBACK(THIS.DBConnection.Sqlhandle) IF TXNLEVEL() > 0 ROLLBACK ENDIF SQLSETPROP(THIS.DBConnection.Sqlhandle,"transActions",1) && Automatic Transaction OTHERWISE IF TXNLEVEL() > 0 ROLLBACK ENDIF ENDCASE ENDFUNC *- FUNCTION DESTROY() THIS.ROLLBACK() THIS.DBConnection = NULL DODEFAULT() ENDFUNC ENDDEFINE