G-3310: Never commit within a cursor loop.
Critical
Efficiency, Reliability
Reason
Doing frequent commits within a cursor loop (all types of loops over cursors, whether implicit cursor for loop or loop with explicit fetch from cursor or cursor variable) risks not being able to complete due to ORA-01555, gives bad performance, and risks that the work is left in an unknown half-finished state and cannot be restarted.
- If the work belongs together (an atomic transaction) the
commit
should be moved to after the loop. Or even better if the logic can be rewritten to a single DML statement on all relevant rows instead of a loop, committing after the single statement. - If each loop iteration is a self-contained atomic transaction, consider instead to populate a collection of transactions to be done (taking restartability into account by collection population), loop over that collection (instead of looping over a cursor) and call a procedure (that contains the transaction logic and the
commit
) in the loop (see also G-3320).
Example (bad)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Example (good)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Example (best)
(Assuming suitable foreign key relationship exists to allow updating a join.)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|