When you are dealing with transactional ASP scripts, you may want to be able to directly affect the outcome of the transaction that the script is encapsulating. As in the server components that support transactions, you will refer to the current transaction using the ObjectContext
object. This object provides the encapsulation for all of the transaction-handling routines that a developer may need. This is exactly the same object that the server components participating in the transaction will be accessing. There are two methods that this component provides that can be accessed from ASP scripts.
SetComplete
The SetComplete
method declares that the script is not aware of any reason for the transaction not to complete. If all components participating in the transaction also call SetComplete
, the transaction will complete. The SetComplete
method will be implicitly called when the ASP script reaches the end of the script, and SetAbort
has not been called.
SetAbort
The SetAbort
method declares that the transaction initiated by the script has not completed and the resources should not be updated.
Here is a step-by-step example of an ASP script that shows both the @TRANSACTION
directive, and the use of the ASP ObjectContext
object.
<%@ TRANSACTION = Required %>
This is the required first line of the script. It indicates that this script must be within the bounds of a transaction. Since a transaction cannot span multiple ASP scripts, there will be no active transaction when this page starts. This will force MTS to create a new transaction which will encompass this page and the two components referenced from it.
<%
Set objOnHand = Server.CreateObject("BookComp.OnHand")
Set objSales = Server.CreateObject("BookComp.Sales")
Even though this page is within a transaction, the usual Server.CreateObject
method is used to create references to the OnHand
and Sales
components. Since MTS is providing the environment for this page, they will be created within the current object context of the transaction for this page. In this example, the values of Quantity
and ProductID
have been passed into this ASP file.
iQuantity = Request("Quantity")
ProductID = Request("ProductID")
strStatus = objOnHand.CheckOnHand(iQuantity,ProductID)
If strStatus = "INS"
ObjectContext.SetAbort
Response.Write "At this time, inventory levels are insufficient to complete your transaction"
When the value of strStatus
is INS
, the server component method indicated that there was insufficient inventory to process the request. The SetAbort
method is explicitly called by the script to indicate that this transaction should not be completed. The script then outputs a message to the user indicating that the transaction was unable to complete. If the CheckOnHand
method performed any database modifications, such as requesting that items be removed from inventory, then the act of aborting the transaction will cause any changes to the database to be rolled back.
By performing the return value check and calling SetAbort
in the ASP script, some of the business rule processing is being handled at this level. But earlier in this chapter, we showed how business logic should be encapsulated within application components. Why wouldn't the CheckOnHand
method call SetAbort
itself when it determined insufficient inventory available?
This is an example of a business object that can be used for multiple purposes. There may be instances where a failure to have sufficient inventory is not reason enough to abort a transaction in progress. If the call to SetAbort
had been in the method itself, then anytime this method was invoked within a transaction and there was insufficient inventory, the entire transaction would be aborted. There probably exists a case where a developer would not want this to happen. By putting the transaction decision logic in the ASP script, and not in the method itself, this decision can be made depending on the context of the application when the method is invoked.
Else
ObjectContext.SetComplete
acctInfo = Request("AcctInfo")
Update = objSales.ProcessSale(acctInfo)
End If
%>
If the inventory check was successful, then the sale transaction may continue. Since all of the processing that needs to be done by the script has completed successfully, the SetComplete
method is called. It is not necessary to explicitly call this method, since it will be called once the script reaches the end. The final part of the script invokes the ProcessSale
method to complete the sale. If for any reason this method fails, then the transaction can still be aborted. All that calling SetComplete
did was indicate to MTS that the script processing completed successfully. It did not commit the transaction. The transaction is only committed when all components participating in the transaction provide the SetComplete
indication.
If there were an error in the ProcessSale
method then the transaction would be aborted. There are two ways that the script can be notified of this occurring. The script could check the return value from the ProcessSale
method in the same manner it checked the return value from the CheckOnHand
method. If the return value indicated an error, then the script could handle it accordingly. The other way that the script could handle a transaction abort is by handling a transaction event.