The Java documentation of the interface java.sql.Connection says this about the close() method: "It is strongly recommended that an application explicitly commits or rolls back an active transaction prior to calling the close method. If the close method is called and there is an active transaction, the results are implementation-defined."
This creates a subtle but serious problem: If I call the rollback() method of a Connection but this method fails (for example, a timeout occurs), then can I call the close() method of this Connection? Is it possible that there is still an active transaction when I call the close() method, and so the results are implementation-defined, and so the transaction may be committed?
I can choose to not call the close() method if the rollback() fails, but this may make the JDBC resources not released. Furthermore, maybe eventually the close() method will be called (maybe when the Connection object is garbage-collected). If this is the case, then this approach will not help.
So, what should I do when the rollback() method of a Connection fails? If the rollback() method fails, can I still call the close() method of this Connection?
9. Which of the following is used to rollback a JDBC transaction? Explanation: rollback() method is used to rollback the transaction. It will rollback all the changes made by the transaction.
If you don't close it, it leaks, and ties up server resources. @EJP The connection itself might be thread-safe (required by JDBC), but the applications use of the connection is probably not threadsafe. Think of things like different transaction isolation, boundaries (commit/rollback/autocommit) etc.
rollback. Undoes all changes made in the current transaction and releases any database locks currently held by this Connection object. This method should be used only when auto-commit mode has been disabled.
If I call the
rollback()
method of aConnection
but this method fails (for example, a timeout occurs), then can I call theclose()
method of thisConnection
?
According to the JDBC specification, SQLTransactionRollbackException
is a Transient SQLException
.
A Transient
SQLException
will be thrown in situations where a previously failed operation might be able to succeed when the operation is retried without any intervention by application-level functionality. After a TransientSQLException
other thanSQLTransientConnectionException
occurs, the application can assume that the connection is still valid.
So, if the rollback()
failed with an SQLTransactionRollbackException
, you should be able to close()
the connection, or retry the rollback()
. (If you called close()
, after calling rollback()
it would be perverse for the driver to commit the transaction.)
However, if the rollback()
failed with a SQLTransientConnectionException
the connection will be invalid. Calling close()
could fail ... or it might commit the transaction1. The cautious approach is to just abandon the Connection
, and trust that the database will rollback the transaction automatically. Alternatively, if you can figure out (from your driver's documentation, etc) that a close()
won't commit a transaction, then call close()
.
In the latter case, I think we should assume that when the JDBC driver detected that the connection has been lost it would release the Socket
and other resources, as far as possible. A Socket
whose network connection has been broken cannot be "reopened" so there is no point hanging on to it.
If we didn't call close()
and just forgot about the Connection
(after a rollback failure), the resource leak probably doesn't matter since:
Connection
and release the associated Socket
etcetera.1 - In theory. The JDBC Javadocs say that it is unspecified what happens if you close()
a connection with an active transaction. But it would be worth checking the documentation for the specific drivers that you are using.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With