* Save invoice header and details in a transaction. * This is only a sketch of the real code, which would * probably include various error checking and handling. BEGIN TRANSACTION
lGoOn = .T.
SELECT header IF NOT TABLEUPDATE() lGoOn = .F. ENDIF
IF lGoOn SELECT detail
IF NOT TABLEUPDATE(.t.,.t.) lGoOn = .F. ENDIF ENDIF
IF lGoOn END TRANSACTION ELSE ROLLBACK =TABLEREVERT(.f.,"header") =TABLEREVERT(.t.,"detail") ENDIF
You may be confused by the calls to TableRevert() after the Rollback. What's going on here is that updating is normally a two-step process. The user updates the buffers by making changes (through whatever interface you provide). Then, calls to TableUpdate() copy the changes from the buffers to the actual tables. When you use transactions, you add another layer to that. TableUpdate() copies the changes from the buffers to another set of buffers (call them "transaction buffers") and END TRANSACTION copies from those buffers to the actual tables.
When you issue ROLLBACK, the changes are cleared from the transaction buffers, but the original buffers still contain the changed data. The TableRevert() calls discard those changes. In a real application, you probably wouldn't just give up and revert your changes like that, but would try to solve whatever problems prevented the save, and try again.