When a mainframe DB2 application calls a stored procedure flow of any form, a sequence of serial chained transactions is executed. For example, consider the following sequence executed from a COBOL client application:
Insert 1
Call COBOL stored procedure A
Insert 2
Call COBOL routine B
Commit
Insert 3
Rollback
Insert 4
Insert 5
Commit
DB2 inserts records 1,2,4 and 5.
However, with SQL Server, when an application calls a stored procedure flow of any kind, it forms a nested transaction. The outermost transaction of this nested transaction ultimately determines whether to commit or rollback the work of all the transactions contained therein, regardless of what those transactions did. In the above example, because the COBOL client application starts the nested transaction and ends it with a COMMIT, all 5 records are inserted; if the COBOL client application ends with a ROLLBACK instead, none of the 5 records are inserted.
This behavior is not acceptable if you want your migrated SQL Server application to mimic DB2 transaction chaining.
With SQL Server, you can use a combination of implicit_transactions and savepoints. When implicit_transactions are set to OFF or to ON, this positions the lead transaction that commits the workload to SQL Server and releases locks. Savepoints ensure that serially chained COMMIT and ROLLBACK transactions behave as you intend them to.
Note: For more information on setting savepoints and implicit_transactions, see the topics
OPTION,
SET AUTOCOMMIT, and
AUTOCOMMIT.
HCOSS offers three solutions to mimic mainframe DB2 transaction behavior with COBOL stored procedures. The first two begin with implicit_transactions set to OFF, and the third begins with implicit_transactions set to ON. Here, we provide a description of each solution and a summary of the advantages and disadvantages for each.
- Solutions 1 and 2: Caller - Implicit Transactions Off (auto-commit mode)
- You can set implicit_transactions to OFF either by building the application with SQL(AUTOCOMMIT) or by executing an
EXEC SQL SET AUTOCOMMIT ON END-EXEC statement before making the call to a stored procedure. This is auto-commit mode. You can turn auto-commit mode off by executing an
EXEC SQL SET AUTOCOMMIT ON END-EXEC statement after the call to the stored procedure.
HCOSS does the following:
|
ON ENTRY
|
EXEC SQL COMMIT
|
EXEC SQL ROLLBACK
|
ON EXIT (return)
|
Lead (called) Stored Procedure
|
start transaction
set savepoint
|
commit
reset savepoint
|
roll back to savepoint
commit
reset savepoint
|
Option 1:
- roll back to savepoint
- commit
Option 2: Use SQL(OPTION=SPCOMMITONRETURN)
|
Nested Stored Proceduress
|
|
reset savepoint
|
roll back to savepoint
|
|
Called COBOL Routines
|
|
commit
reset savepoint
|
roll back to savepoint
commit
reset savepoint
|
|
- Solution 1: Keep nested Stored Procedures
-
Advantages
|
Disadvantages
|
- Minimal code changes:
- No changes to stored procedure code (SQLCLRTRANS compile option)
- Application code might be required to set implicit_transactions to OFF before calling the stored procedure, and back to ON after calling the stored procedure
- Locks are freed by the lead stored procedure when it commits or rolls back workload (concurrency is better than Solution 3)
|
- No work from the client can be committed or rolled back by the stored procedure (integrity is the same as Solution 2, but worse than Solution 3)
- No work from the stored procedure can be committed or rolled back by the client (integrity is the same as same as Solution 2, but worse than Solution 3)
- Locks are held by nested stored procedures (concurrency is worse than Solution 2)
|
- Solution 2: Replace nested Stored Procedures with Called COBOL routines
-
Advantage
|
Disadvantages
|
Locks are freed by the lead stored procedure and called COBOL routines when they commit or rollback (concurrency is better than both Solution 1 and Solution 3)
|
- Code remediation:
- Change nested stored procedure calls to COBOL calls (SQLCLRTRANS compile option)
- Application code might be required to set implicit_transactions to OFF before calling the stored procedure, and back to ON after calling the stored procedure
- No work from the client can be committed or rolled back by the stored procedure (integrity is the same as Solution 2, but worse than Solution 3)
- No work from the stored procedure can be committed or rolled back by the client (integrity is the same as same as Solution 2, but worse than Solution 3)
|
- Solution 3: Caller - Implicit Transactions On
- Implicit_transaction is set to ON before the call to a stored procedure. Auto-commit mode is turned off. In this solution, nested Stored Procedures remain intact.
HCOSS does the following:
|
ON ENTRY
|
EXEC SQL COMMIT
|
EXEC SQL ROLLBACK
|
ON EXIT (return)
|
Lead (called) SP
|
|
reset savepoint
|
roll back to savepoint
|
|
Nested SPs
|
|
reset savepoint
|
roll back to savepoint
|
|
Advantages
|
Disadvantage
|
- Minimal code changes for non-COBOL applications:
- No changes to stored procedure code (compile with SQL(OPTION=SQLCLRTRANS))
- Application code must set a savepoint before the stored procedure call
- Application code must issue a commit or rollback after the stored procedure call
- If additional SP calls are made, the pplication code must set a savepoint
- Minimal code changes for COBOL applications:
- Compile with SQL(OPTION=SQLCLRTRANS)
- Application code must issue a commit or rollback after the stored procedure call
- Because all work is committed and rolled back by the client, work cannot be lost (integrity is better than both Solution 1 and Solution 2)
|
Locks acquired by stored procedures are not released until the client commits or rolls back (concurrency is worse than both Solution 1 and Solution 2)
|