views:

2282

answers:

7

The in-house application framework we use at my company makes it necessary to put every SQL query into transactions, even though if I know that none of the commands will make changes in the database. At the end of the session, before closing the connection, I commit the transaction to close it properly. I wonder if there were any particular difference if I rolled it back, especially in terms of speed.

Please note that I am using Oracle, but I guess other databases have similar behaviour. Also, I can't do anything about the requirement to begin the transaction, that part of the codebase is out of my hands.

A: 

Since you've not done any DML, I suspect there'd be no difference between a COMMIT and ROLLBACK in Oracle. Either way there's nothing to do.

cagcowboy
+3  A: 

In general a COMMIT is much faster than a ROLLBACK, but in the case where you have done nothing they are effectively the same.

Tony Andrews
+6  A: 

I agree with the previous answers that there's no difference between COMMIT and ROLLBACK in this case. There might be a negligible difference in the CPU time needed to determine that there's nothing to COMMIT versus the CPU time needed to determine that there's nothing to ROLLBACK. But, if it's a negligible difference, we can safely forget about about it.

However, it's worth pointing out that there's a difference between a session that does a bunch of queries in the context of a single transaction and a session that does the same queries in the context of a series of transactions.

If a client starts a transaction, performs a query, performs a COMMITor ROLLBACK, then starts a second transaction and performs a second query, there's no guarantee that the second query will observe the same database state as the first query. Sometimes, maintaining a single consistent view of the data is of the essence. Sometimes, getting a more current view of the data is of the essence. It depends on what you are doing.

I know, I know, the OP didn't ask this question. But some readers may be asking it in the back of their minds.

Walter Mitty
+5  A: 

Databases often preserve either a before-image journal (what it was before the transaction) or an after-image journal (what it will be when the transaction completes.) If it keeps a before-image, that has to be restored on a rollback. If it keeps an after-image, that has to replace data in the event of a commit.

Oracle has both a journal and rollback space. The transaction journal accumulates blocks which are later written by DB writers. Since these are asychronous, almost nothing DB writer related has any impact on your transaction (if the queue fills up, then you might have to wait.)

Even for a query-only transaction, I'd be willing to bet that there's some little bit of transactional record-keeping in Oracle's rollback areas. I suspect that a rollback requires some work on Oracle's part before it determines there's nothing to actually roll back. And I think this is synchronous with your transaction. You can't really release any locks until the rollback is completed. [Yes, I know you aren't using any in your transaction, but the locking issue is why I think a rollback has to be fully released then all the locks can be released, then your rollback is finished.]

On the other hand, the commit is more-or-less the expected outcome, and I suspect that discarding the rollback area might be slightly faster. You created no transaction entries, so the db writer will never even wake up to check and discover that there was nothing to do.

I also expect that while commit may be faster, the differences will be minor. So minor, that you might not be able to even measure them in a side-by-side comparison.

S.Lott
I don't recognise this as a description of the way oracle works at all. It sounds like a generic description that has been applied to Oracle. Guesses at how Oracle works are not likely to be helful.
David Aldridge
Oracle calls the journal a "Redo Log File". It calls the rollback segments an "Undo Tablespace". Do you know which is quicker? Commit or rollback?
S.Lott
If there's no work to do then there's almost certainly no difference. Oracle is optimised to commit fast -- it only requires that the commit record be written to the redo log buffer and the buffer flushed (except for asynchronous commit in 10g+). A rollback is more work.
David Aldridge
At http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1519405621318#tom64214016687322, Tom Kyte indicates that the database will not actually do any commit work if there is no transaction. You could probably check that will by doing a few hundreds commits really quick and checking the count of log file sync events.
Gary
+2  A: 

The documentation states that:

  • Oracle recommends that you explicitly end every transaction in your application programs with a COMMIT or ROLLBACK statement, including the last transaction, before disconnecting from Oracle Database. If you do not explicitly commit the transaction and the program terminates abnormally, then the last uncommitted transaction is automatically rolled back. A normal exit from most Oracle utilities and tools causes the current transaction to be committed. A normal exit from an Oracle precompiler program does not commit the transaction and relies on Oracle Database to roll back the current transaction.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_4010.htm#SQLRF01110

If you want o choose to do one or the other then you might as well do the one that is the same as doing nothing, and just commit it.

David Aldridge
It depends on the client actually. sqlplus, its an implicit commit. others it might not be.If the network connection is severed (eg, the client just "goes away"), then its a rollback.
Matthew Watson
I'm not sure that it doesdepend on the application, I should probably have said a "graceful disconnect", but the docs say that "An implicit request occurs after normal termination of an application or ..." http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/transact.htm#CNCPT1119
David Aldridge
Actually, I found a better reference and edited my posting. Thanks.
David Aldridge
+1  A: 

Well, we must take into account what an SELECT returns in Oracle. There are two modes. By default an SELECT returns data as that data looked in the very moment the SELECT statement started executing (this is default behavior in READ COMMITTED isolation mode, the default transactional mode). So if an UPDATE/INSERT was executed after SELECT was issued that won't be visible in result set.

This can be a problem if you need to compare two result sets (for example debta and credit sides of an general ledger app). For that we have a second mode. In that mode SELECT returns data as it looked at the moment the current transaction began (default behavior in READ ONLY and SERIALIZABLE isolation levels).

So, at least sometimes it is necessary to execute SELECTs in transaction.

Petar Repac
A: 

How are you starting a transaction? Please provide the specific code.