Usage of Commit Statement - oracle

How do I use the Commit statement correctly? Do I have to use commit statement for every insert statement and every function? For example, if I alter a table to add a column do I have to use a commit statement?

If you run a DDL statement (CREATE, ALTER, DROP, GRANT, etc) then:
Oracle Database implicitly commits the current transaction before and after every DDL statement.
If you run a DML statement (INSERT, UPDATE, DELETE, SELECT, CALL, MERGE) then:
These statements do not implicitly commit the current transaction.
and you will need to manually commit the uncommitted transactions (but you do not have to COMMIT after every statement).
If you want to perform a partial rollback then you can use SAVEPOINTs.
You should not put COMMIT statements in functions or procedures so that you can use multiple functions/procedures in a single transaction and then COMMIT or ROLLBACK that entire transaction.

Commits are needed when you change data in your tables (insert, update and delete). As long as you do not commit, other users will not see the changed data and you still have the option to undo the changes by executing a rollback.
There is no need to commit after every single statement.
Commits are not needed when changing the table itself (alter table). In fact, the alter table statement issues an implicit commit.
Some more on implicit/explicit commit statements in Oracle

Based on accumulated experience and "good practices" - you should not implement "commit" statements in your functions/procedures (most of the time, depends on the task, what are you try to achieve). The "commit" decision should lie on the user, who invokes your function/procedures.
What you can implement, is a "rollback", when exceptions are occurred/caught.
Often, when stored procedures or function are invoked from the application/web part, they are auto-committed (the option can be changed within transaction methods, as far i know, at least in java).

try like that:
try {
// First of all, let's begin a transaction
$db->beginTransaction();
// A set of queries; if one fails, an exception should be thrown
$db->query('first query');
$db->query('second query');
$db->query('third query');
// If we arrive here, it means that no exception was thrown
// i.e. no query has failed, and we can commit the transaction
$db->commit();
} catch (Exception $e) {
// An exception has been thrown
// We must rollback the transaction
$db->rollback();
}

Related

Is commit required in an Oracle stored procedure which is called from Java class?

I have an Oracle Stored Procedure that does some inserts and updates on a table in DB.
There is no explicit Commit or Rollback statement at the end of the procedure.
However, when I call this SP through a java class, I see that the inserts and updates are committed into the DB.
So can anyone help me understand if we really need a commit statement at the end of the stored procedure in Oracle?
I am not java experience but as far as I know when you close the connection of the database the data are committed (unless if you rollback them). Now to return into your question is when to use the commit in SP.
When you use DML(insert,update,delete) operation in the procedure on a table, the table will be Locked therefore if any other user try to access the locked table, it has to wait till you commit/rollback your operation. so if your procedure was taking time, due to a long loop or bad optimized query then the user will be blocked. So if you had a commit before the DMl, the no blocks will happen.
Other reason, is the undo tablespace, where all the data not committed will wait there till you commit them, so if for example you inserted lot of data (millions), your undo might get full depend on your size and youll get an error.
so short answer , if your procedure doesn't has lot of operations on big tables and it fast then you can pass by the commit , otherwise it better to add commits.

What is meant by PRAGMA AUTONOMOUS_TRANSACTION?

I need a clarity about pragma autonomous transaction. I have used a overlap select query in trigger and insert query in procedure. If I import two records in single file, the 2nd record is same as 1st record so the second record should be shown as overlap error. Now the select query in trigger executes but the error is not thrown by using the pragma autonomous transaction.
AUTONMOUS_TRANSACTION is a nested transaction. It executes DML independently of the calling transaction. So a query issued in an autonomous transaction won't see any uncommitted changes in the outer transaction. This is why you don't see your error message: the invalid state only exists in the uncommitted changes of the transaction.
Obviously you are using AUTONMOUS_TRANSACTION to avoid a mutating table error. However, a better solution would be to use a COMPOUND DML trigger: use a FOR EACH ROW to store the changes in an array, then verify them for no overlaps in the AFTER statement stage. Find out more.

Why is it not allowed to use a ROLLBACK statement in a PL/SQL trigger, but RAISE_APPLICATION_ERROR is?

Correct me if I'm wrong, but I was under the impression that a call to RAISE_APPLICATION_ERROR() forces a ROLLBACK. How is it possible that a call to RAISE_APPLICATION_ERROR() is allowed in PL/SQL triggers when ROLLBACK statements and/or methods that execute ROLLBACK statements are not?
I have the feeling I am missing a crucial point here :)
Thanks in advance!
Consider yourself corrected. Sort of. Raising (or encountering) an exception doesn't cause a rollback of the curent transaction. From the documentation:
In most cases, if a trigger runs a statement that raises an exception, and the exception is not handled by an exception handler, then the database rolls back the effects of both the trigger and its triggering statement.
Note that it's the statement, not the transaction; but "roles back the effect of" is a little confusing I suppose...
There is an implicit savepoint around every statement, and the trigger exception rolls back to that savepoint (except for after triggers etc. as noted in the docs). From Tom Kyte's Expert Oracle Database Architecture:
Oracle achieves this statement-level atomicity by silently wrapping a SAVEPOINT aroind each of our calls to the database.
Inside a trigger a RAISE_APPLICATION_ERROR does not perform a ROLLBACK, it aborts the current operation, i.e. a single UPDATE/INSERT/DELETE. Everything inside a trigger belongs to such an operation (thats' also the reason for famous error "ORA-04091 - Table is mutating, trigger/function may not see it").
A Rollback reverts all changes within current transaction (or up to given Savepoint), that's different.

BEGIN - END block atomic transactions in PL/SQL

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.
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.
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. Nevertheless, in PL/SQL you (the client) must always issue a commit or rollback for the transaction.
If you wish to have atomic transactions within a PL/SQL containing transaction, you need to declare a PRAGMA AUTONOMOUS_TRANSACTION in the declaration block. This will ensure that any DML within that block can be committed or rolledback independently of the containing transaction.
However, you cannot declare this pragma for nested blocks. You can only declare this for:
Top-level (not nested) anonymous PL/SQL blocks
List item
Local, standalone, and packaged functions and procedures
Methods of a SQL object type
Database triggers
Reference: Oracle
You don't mention if this is an anonymous PL/SQL block or a declarative one ie. Package, Procedure or Function.
However, in PL/SQL a COMMIT must be explicitly made to save your transaction(s) to the database. The COMMIT actually saves all unsaved transactions to the database from your current user's session.
If an error occurs the transaction implicitly does a ROLLBACK.
This is the default behaviour for PL/SQL.
The default behavior of Commit PL/SQL block:
You should explicitly commit or roll back every transaction. Whether you issue the commit or rollback in your PL/SQL program or from a client program depends on the application logic. If you do not commit or roll back a transaction explicitly, the client environment determines its final state.
For example, in the SQLPlus environment, if your PL/SQL block does
not include a COMMIT or ROLLBACK statement, the final state of your
transaction depends on what you do after running the block. If you
execute a data definition, data control, or COMMIT statement or if you
issue the EXIT, DISCONNECT, or QUIT command, Oracle commits the
transaction. If you execute a ROLLBACK statement or abort the SQLPlus
session, Oracle rolls back the transaction.
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/sqloperations.htm#i7105

triggers statement level atomicity

What does Oracle mean by "statement level atomicity"?
Let's cite a couple of chapters from the Concepts:
Statement-Level Read Consistency
Oracle always enforces statement-level read consistency. This guarantees that all the data returned by a single query comes from a single point in time--the time that the query began. Therefore, a query never sees dirty data nor any of the changes made by transactions that commit during query execution. As query execution proceeds, only data committed before the query began is visible to the query. The query does not see changes committed after statement execution begins.
Statement-Level Rollback
If at any time during execution a SQL statement causes an error, all effects of the statement are rolled back. The effect of the rollback is as if that statement had never been run. This operation is a statement-level rollback.
A SQL statement that fails causes the loss only of any work it would have performed itself. It does not cause the loss of any work that preceded it in the current transaction.
It means that any single SQL statement you run is atomic in nature - it will either succeed completely or fail completely. If your SQL statement fails, and triggers that would have run as a result of that SQL statement will fail as well.
This is a statement about the nature of transactions: a Unit Of Work either succeeds or completes in its entirety. If your transaction comprises two inserts plus an update, and the update statement fails, the database will rollback all three statements. Any recursive SQL or other SQL such as that included in triggers is included in the atomic scope of the transaction. Find out more.
Atomicity means the A in the ACID principles of transaction management.

Resources