Oracle: DDL and transaction rollback - oracle

Could in Oracle DDL (create/alter) be transactional like they are in MS SQL (started from 2005)?

DDL is not transactional in Oracle. From the 11.2 doc:
Oracle Database implicitly commits the current transaction before and after every DDL statement.

No. In Oracle DDL statements themselves are not transactional.
Running a DDL statement will implicitly commit any open transaction for that session before starting the actual work.
In addition some statements, like an alter table statement, may fail if another session has an open transaction on the object being modified or one of its dependencies. You can set a ddl_lock_timeout to specify how long you want Oracle to wait for the object to become available.
See DDL Statements for a summary of types of DDL statements and information about their behaviour regarding locks and transactions.
Oracle Database implicitly commits the current transaction before and after every DDL statement.

Just discovered this, so needs more investigation, but Oracle's create schema authorization at least allows to bundle several DDL statements in a single transaction, thus avoiding several commits, and guarantees no side-effects, i.e. a rollback, if any one of the DDL statement fails.
It is unclear whether the rollback applies to the wrapped DDL statements only, as-if the create schema started a save-point, or the outer transaction with possibly some prior DML statement.
You still cannot avoid the commit after the last wrapped DDL statement complete successfully though.

Related

Oracle database transaction

I have a question about transactional queries on oracle Db(or other RDBMS).
I have for instance 3 tables in my transactionnal script. What happen if I call begin transaction on each of three tables and at the end I command commit also on each table?
Is it necessary to do that?

Explain Oracle's Backend process when executing DDL and DML

What will happen in the backend when we execute a SQL Statement in an Oracle Database?
There are different process for both DDL and DML. For example DML reads data to the buffer cache and once commit is issued, it will only then update to DB.
Likewise i need to know the entire back end process when a query executed in oracle.
Please explain for both DDL and DML.

Oracle - Transaction with a series of DDL statements

I have a series of rename table ddl statements that I would like to run within a transaction. During this period, there will also be other sessions that will be running as well which might hijack the tables used for the rename above and cause a resource contention/deadlock.
Is it possible to achieve that in Oracle? Understand that each ddl statements will commit after each execution which will free up the tables for other sessions to hijack. How can I ensure that the current session that is executing the DDL statments complete successfully before other sessions can access the tables?
--LOCK TABLE a
RENAME tbl a to b
--possible contention as commit release the lock on tbl a
RENAME tbl b to c
RENAME tbl c to d
--commit
DDL statements in Oracle are each a transaction. Each DDL statement causes few or many changes in the data dictionary, like obj$. I am not sure, but looking at the major work Oracle has gone through to ensure that locking is not an issue with even the early versions of their platform, I think they found it easier to commit per DDL statement to keep the locks short in time and avoiding dead locks within a session or between sessions doing DDL. Under some circumstances, you can still feel that the Oracle kernel doesn't lock dropping and creating to many objects during production use with ORA-600 thrown at your head.
As a workaround, you can either use the datamodel versioning introduced a few years ago. I have no working experience with it since it is too restricted for my work, but you can find more on it by googling on 'Edition-based redefinition' or going to Oracle manual. It might not be available in the licensed edition of Oracle you are working on.
As a workaround, you can execute the statements during uptime. But this will generally break sessions unless the code your users are executing automatically recovers easily. Remember that each object has an ID and a name. Changing the name might not change the ID, so many pointers to the object will need to be refreshed, leading to ORA-4063 or alike. Oracle has no pause/suspend for sessions as far as I know.

Is there something similar to commit for DDL?

When I want to update, delete, insert I need to commit. That's helpful most of the time, I might update wrong information or delete something by mistake and I can undo that.
When dropping a column, I don't need a commit. Is there something like rollback (not flashback), which enables me to undo my changes quickly? Dropping a column, even after a long analysis can probably cause damage to the table (pk, fk).
Why did Oracle provided a commit for DML but not for DDL?
Why did Oracle provided a commit for DML but not for DDL?
When you issue a DDL statement, you basically start a transaction against the Oracle data dictionary, and this transaction, to eliminate any overheads, has to be as short as possible and take effect as soon as possible. Because of this, DDL statement does double commit, before the DDL statement and then right after(or rollback, if something went wrong) the statement. This behavior makes Oracle's DDL not transactional DDL and you cannot commit or rollback it explicitly. It's just the way it is.
Having said that, if you dropped a table, then starting from 10g and up you can use flashback table technology to get it back in one statement, because Oracle, after you issue drop table statement wont drop it, it rather puts it in the recycle bin:
flashback table <<table_name>> to before drop
Unfortunately you cannot use flashback table, to restore a dropped column of a table, simply because dropped column wont be placed in the recycle bin. You will have to perform a point in time recovery of your full database or a single tablespace, or if there is a logical backup(*.dmp file), restore table from it by using imp or impdp utility.

Workaround to Auto Commit Of DDL Statements Before Execution

I am keeping two passwords (actually the same password as far as website human user knows,but hashed and salted using two different algorithms and salts) for my website. One is place in WebUsers table and that is where password is verified when users login at website. The other is password of an oracle user, each website user corresponds to an oracle user.
When making change password procedure, I have to change password in WebUsers table as well as in oracle, in a transaction. The problem is, the DDL statement [alter user ...] commit before performing any action. If [alter user ...] fail and in the exception handling code I rollback the transaction, the changes in the WebUsers table are not rollbacked. Is there some work around?
There is just no way to have a DML and DDL in one atomic transaction under Oracle.
In Oracle a a DDL will always explicitly result in a commit before running the DDL.
Typically in these sort of scenarios, you should execute the step that's most likely to fail first, i.e. in your case the DDL 'Alter User'.
And then run your DML , only if the DDL succeeds , but then again, there is this issue of the DML failing, and then not being able to rollback the DDL, at which point you'll simply have to run another DDL to revert the changes made by the first DDL.
The idea is that the second step is far more likely to fail than the first step.
This pattern is also used, where you've to deal with say something like JMS + JDBC , and you can't use a JTA transaction to wrap the JMS + JDBC activities in a single transcation.

Resources