Just before the action object is destroyed, it checks a module-level variable (bPiTransactionOK) in the class Terminate event to see whether the transaction should be committed. This module-level variable can be set by any of the procedures within the action object. Normally, if a transaction has to be rolled back, an exception is raised to the client and bPiTransactionOK is set to False so that the user can be informed that something very bad has happened. Checking this module-level variable in the Terminate event ensures that the action object is responsible for protecting the transaction, not the client.
Private bPiTransactionOK As Boolean Private oPicDAL As cDAL Private Sub Class_Initialize() Set oPicDAL = New cDAL oPicDAL.BeginTransaction bPiTransactionOK = True End Sub Private Sub Class_Terminate() If bPiTransactionOK Then oPicDAL.CommitTransaction Else oPicDAL.RollbackTransaction End If End Sub
So now we've covered the role and design of action objects. In summary, a good analogy is that of a relational SQL database: factory-worker objects are represented by the tables and records, and action objects are represented by the stored procedures. The lifetime of the action object controls the lifetime of the implicit transaction contained within.
Action objects should be accessed in a stateless fashion-get what you want and then get the hell out of there! Stateless fashion is enabled by the supporting of serialization by cRecordset and cParams, which ensures that your applications can achieve good distributed performance.