Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BEGIN - END block atomic transactions in PL/SQL

Tags:

oracle

plsql

This information should be easy to find, but I haven't had any luck.

When I have a BEGIN - END block in a PL/SQL, does it behave as an atomic transaction, that will try to commit on hitting the END block and if anything goes wrong rolls back the changes?

If not, how do I make sure that the code inside the BEGIN - END block behaves like an atomic transaction and how does the block behave "by default"?

EDIT: I am running from a stored procedure and I am using an implicit block, I think.

like image 527
Jan Kratochvil Avatar asked Aug 15 '12 08:08

Jan Kratochvil


People also ask

How does an execution block start and end in PL SQL?

A PL/SQL block has an executable section. An executable section starts with the keyword BEGIN and ends with the keyword END . The executable section must have a least one executable statement, even if it is the NULL statement which does nothing.

What is begin in PL SQL?

BEGIN - END blocks are the building blocks of PL/SQL, and each PL/SQL unit is contained within at least one such block. Nesting BEGIN - END blocks within PL/SQL blocks is usually done to trap certain exceptions and handle that special exception and then raise unrelated exceptions.

What is begin end in Oracle?

BEGIN ... END syntax is used for writing compound statements, which can appear within stored programs (stored procedures and functions, triggers, and events). A compound statement can contain multiple statements, enclosed by the BEGIN and END keywords.

What is purpose of Begin and exception section in PL SQL?

PL/SQL allows you to define your own exceptions according to the need of your program. A user-defined exception must be declared and then raised explicitly, using either a RAISE statement or the procedure DBMS_STANDARD.


1 Answers

Firstly, BEGIN..END are merely syntactic elements, and have nothing to do with transactions.

Secondly, in Oracle all individual DML statements are atomic (i.e. they either succeed in full, or rollback any intermediate changes on the first failure) (unless you use the EXCEPTIONS INTO option, which I won't go into here).

If you wish a group of statements to be treated as a single atomic transaction, you'd do something like this:

BEGIN   SAVEPOINT start_tran;   INSERT INTO .... ; -- first DML   UPDATE .... ; -- second DML   BEGIN ... END; -- some other work   UPDATE .... ; -- final DML EXCEPTION   WHEN OTHERS THEN     ROLLBACK TO start_tran;     RAISE; END; 

That way, any exception will cause the statements in this block to be rolled back, but any statements that were run prior to this block will not be rolled back.

Note that I don't include a COMMIT - usually I prefer the calling process to issue the commit.


It is true that a BEGIN..END block with no exception handler will automatically handle this for you:

BEGIN   INSERT INTO .... ; -- first DML   UPDATE .... ; -- second DML   BEGIN ... END; -- some other work   UPDATE .... ; -- final DML END; 

If an exception is raised, all the inserts and updates will be rolled back; but as soon as you want to add an exception handler, it won't rollback. So I prefer the explicit method using savepoints.

like image 122
Jeffrey Kemp Avatar answered Oct 06 '22 20:10

Jeffrey Kemp