In a COBOL batch program what is better in performance terms?
With commit:
IF SW-NEW-TRANSACT
EXEC SQL
COMMIT
END-EXEC
END-IF.
PERFORM SOMETHING
THRU SOMETHING-EXIT.
IF SW-ERROR
EXEC SQL
ROLLBACK
END-EXEC
END-IF.
With syncpoints:
IF SW-NEW-TRANSACT
EXEC SQL
SAVEPOINT NAMEPOINT ON ROLLBACK RETAIN CURSORS
END-EXEC
END-IF.
PERFORM SOMETHING
THRU SOMETHING-EXIT.
IF SW-ERROR
EXEC SQL
ROLLBACK TO SAVEPOINT NAMEPOINT
END-EXEC
END-IF.
SAVEPOINTs and COMMITs are not interchangeable.
A process always has to COMMIT or ROLLBACK database work at some point. A COMMIT is
taken between transactions (between complete units of work). COMMIT may be taken after each transaction or, as is common in batch processing,
after some multiple number of transactions. A COMMIT should
never be taken mid-transaction (this defeats the UNIT OF WORK concept).
A SAVEPOINT is generally taken and possibly released within a single unit of work. SAVEPOINTs should always be released upon completion of
a unit of work. They are always released upon a COMMIT.
The purpose
of a SAVEPOINT is to allow partial backout from within a unit of work. This is useful when a process begins with a sequence of common
database inserts/updates followed by a process branch where some updates may be performed before it can be determined that the alternate process
branch should have been executed. The SAVEPOINT allows backing out of the “blind alley” branch and then continuing on with the alternate
branch while preserving the common “up front” work. Without a SAVEPOINT, backing out of a “blind alley” might have required extensive data
buffering within the transaction (complex processing) or a ROLLBACK and re-do from the start of the transaction with some sort of flag
indicating that the alternative process branch needs to be followed. All this leads to complex application logic.
ROLLBACK TO SAVEPOINT has several advantages.
It can preserve “up front” work, saving the cost of doing it over. It saves rolling back the entire transaction. Rollbacks can be more
“expensive” than the original inserts/updates were and may span multiple transactions (depending on the commit frequency).
Finally, process complexity is generally reduced when database work can be
selectively “undone” through a ROLLBACK TO SAVEPOINT.
How might SAVEPOINT be used to improve the efficiency of your batch program? If your transactions employ self induced rollbacks to recover
from “blind alley” processing, then SAVEPOINT can be a huge benefit. Similarly, if the internal processing logic is complicated by the
need to avoid performing database updates for similar “backout” requirements, then SAVEPOINT can be used to refactor the process into
something that is quite a bit simpler and probably more efficient. Outside of these factors, SAVEPOINT is not going to affect performance
in a positive manner.
Some claim that having a high COMMIT frequency in a batch program reduces performance. Consequently, the lower the commit frequency
the better the performance. Tuning COMMIT frequency is not trivial. The lower the commit frequency, the longer database resources are
held and consequently, the greater the probability of inducing database timeouts. Suffering a database timeout generally causes
a process to rollback. The rollback is a very expensive operation. ROLLBACKs are a big hit to the DBMS itself and
your transaction needs to re-apply all of the updates a second time once it is restarted. Lowering commit frequency can end up
costing you a lot more than it gains. BEWARE!
EDIT
Rule of thumb: Commits have a cost. Rollbacks have a higher cost.
Discounting rollbacks
due to bad data, device failure and program abends (all of which should be rare), most rollbacks are caused by
timeout due to resource contention among processes. Doing fewer commits increases db contention. Doing
fewer commits may improve performance. The trick
is to find where performance gained in not committing out weights the cost of rollbacks due to contention. There
are a large number of factors that influence this – may of them dynamic. My overall advice is to look elsewhere
to improve performance – tuning commit frequency (where timeouts are not the issue) is generally a low return
investment.
Other more fruitful ways to improve batch preformance often involve: