Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In JDBC, what should I do if a Connection fails to rollback?

Tags:

java

jdbc

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?

like image 575
zhoudu Avatar asked Aug 12 '21 09:08

zhoudu


People also ask

Which is used to rollback a JDBC transaction?

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.

What happens if connection is not closed in JDBC?

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.

What does connection rollback do?

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.


1 Answers

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?

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 Transient SQLException other than SQLTransientConnectionException 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:

  • database connection failures should be a rare occurrence,
  • the Java GC should eventually finalize the 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.

like image 55
Stephen C Avatar answered Oct 22 '22 19:10

Stephen C