Java Distribute Transaction - jta

I want to rollback a transaction which already committed, does JTA support this kind of function?

No, only uncommitted transactions can be rolled back

Related

Read Committed Snapshot Isolation and Transactions

I am considering enabling Read Committed Snapshot Isolation on our SQL 2005 database in an attempt to gain some performance. Does setting this isolation level effect all queries regardless of whether they are using BEGIN TRAN and COMMIT TRAN? According to MSDN:
"Once snapshot isolation is enabled, updated row versions for each transaction are maintained in tempdb."
I am unclear if "transaction" means all sql queries or only queries explicitly using transactions.
Every (useful) statement runs within a transaction. If there isn't an open one when you run a particular query, then by default SQL Server opens one, runs the query, and then commits it. This is called Autocommit mode.
This behaviour can be changed so that it doesn't do that third step automatically (the commit) and leaves the transaction open. That's called Implicit Transaction Mode.

NHibernate transaction management if session is closed

I apologize in advance if this is a duplicate, but I looked around a bit and couldn't find this question.
Let's say I have an NHibernate session and within it, I have a transaction. If I close the session, is it safe to assume that the transaction get committed/rolled back (depending on specifics of what's going on in transaction)?
Thank you!
Usually, if you create a session and a transaction within that session, the changes you make (if any) would not affect the underlying database unless a commit is issued. Otherwise, the transaction is rolled back. From what I understood from your case, you are not issuing a commit, so your transaction would be rolled back.
From NHForge.org:
The ITransaction will perform an implicit rollback when it is
disposed, unless an explicit call to Commit or Rollback has already
occurred. This implicit rollback can indicate a missing call to
Commit, so it generates an alert in NHibernate Profiler. If you
intend to rollback, do it explicitly. Your code will be easier to
understand.

Can I rollback a SQLite transaction after it has been committed?

Is there a way in SQLite to essentially undo the latest transaction after it has been committed?
I'd like to revert the database to the state before a transaction or savepoint. I've looked at the rollback command, but it looks like it is limited to rolling back a pending transaction.
Edit
Could I create a savepoint named "Undo" and wait to release it before starting the next action, or rollback if I need to undo it?
I am not sure if you are using JDBC 3.0. If you are then it supports savepoints. http://www.ibm.com/developerworks/java/library/j-jdbcnew/
Other than doing an on-line backup prior to your transaction, I don't know that it supports a "time machine" to go backwards in time.
Can't you put some application logic in place to record enough to undo the applied operation in audit trail table(s)?
I'm not an SQLite expert, but as far as I've tried, it's only possible to make savepoints inside transactions, but not the opposite.
And AFAIK, reading the online documentation, savepoints and transactions are essencially the same, the difference is the transaction stack in which the savepoints are written. You could open a certain number of savepoints (remembering the stack ordering) and, after checking it'a OK, make a transaction commit. I don't know if this will help you.

What happens to an uncommitted transaction when the connection is closed?

Are they rolled back immediately?
Are they rolled back after some period of time?
Are they left in an uncommitted state?
Is the behavior the same if connection pooling is used and the connections are simply reset?
It can stay open while connection pooling applies. Example: command timeout can leave locks and TXN because the client sends as "abort".
2 solutions:
Test in the client, literally:
IF ##TRANCOUNT <> 0 ROLLBACK TRAN
Use SET XACT_ABORT ON to ensured a TXN is cleaned up: Question 1 and Question 2
I always use SET XACT_ABORT ON.
From this SQL Team blog:
Note that with connection pooling,
simply closing the connection without
a rollback will only return the
connection to the pool and the
transaction will remain open until
later reused or removed from the pool.
This can result in locks begin held
unnecessary and cause other timeouts
and rolling block
From MSDN, section "Transaction Support" (my bold)
When a connection is closed, it is
released back into the pool and into
the appropriate subdivision based on
its transaction context. Therefore,
you can close the connection without
generating an error, even though a
distributed transaction is still
pending. This allows you to commit or
abort the distributed transaction at a
later time.
Uncommitted changes are not visible outside of the connection, so the time of the rollback is irrelevant. So yes, the transaction is eventually rolled back.
The server will rollback immedeatly any uncommited transaction when a session is closed.
The ADO pool is reponsible for clearing any uncommited transaction before returning a transaction to the pool. If you dispose a connection with pending transactions, it will rollback.
Transactions can be started by the client using the ADO API (SqlConnection.BeginTransaction) or by executing an BEGIN TRANSACTION statement. The TDS protocol between client and server has special tokens informing the client when a transaction was started/commited like this so ADO knows that the connection has pending transactions even if they are started in T-SQL code.

Is there a difference between commit and rollback in a transaction only having selects?

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.
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.
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.
In general a COMMIT is much faster than a ROLLBACK, but in the case where you have done nothing they are effectively the same.
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.
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.
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.
I'd think a Commit would be more efficient; since generally you'd expect most DB transactions to be committed; so you would think the DB optimizes for this case (as opposed to trying to be more efficient for a rollback).