2

I asked this question (How do I call java.sql.Connection::abort?) and it led me to another question.

With

java.sql.Connection conn = ... ;

What is the difference between

conn.close();

and

conn.abort(...);

?

ryvantage
  • 13,064
  • 15
  • 63
  • 112

2 Answers2

7

You use Connection.close() for a normal, synchronous, close of the connection. The abort method on the other hand is for abruptly terminating a connection that may be stuck.

In most cases you will need to use close(), but close() can sometimes not complete in time, for example it could block if the connection is currently busy (eg executing a long running query or update, or maybe waiting for a lock).

The abort method is for that situation: the driver will mark the connection as closed (hopefully) immediately, the method returns, and the driver can then use the provided Executor to asynchronously perform the necessary cleanup work (eg making sure the statement that is stuck gets aborted, cleaning up other resources, etc).

I hadn't joined the JSR-221 (JDBC specification) Expert Group yet when this method was defined, but as far as I'm aware, the primary intended users for this method is not so much application code, but connection pools, transaction managers and other connection management code that may want to forcibly end connections that are in use too long or 'stuck'.

That said, application code can use abort as well. It may be faster than close (depending on the implementation), but you won't get notified of problems during the asynchronous clean up, and you may abort current operations in progress.

However keep in mind, an abort is considered an abrupt termination of the connection, so it may be less graceful than a close, and it could lead to unspecified behaviour. Also, I'm not sure how well it is supported in drivers compared to a normal close().

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
0

Consulting the java docs seems to indicate that abort is more thorough than close, which is interesting.

abort...

Terminates an open connection. Calling abort results in: The connection marked as closed Closes any physical connection to the database Releases resources used by the connection Insures that any thread that is currently accessing the connection will either progress to completion or throw an SQLException.

close...

Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released. Calling the method close on a Connection object that is already closed is a no-op.

So it seems if you are only concerned with releasing the objects, use close. If you want to make sure it's somewhat more "thread safe", using abort appears to provide a more graceful disconnect.

Per Mark Rotteveel's comment (which gives an accurate summary of the practical difference), my interpretation was incorrect.

Reference: https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#close--

J E Carter II
  • 1,436
  • 1
  • 22
  • 39
  • abort may abort any existing operations as well. Close simply closes the idle connection and releases resources – Dave Cramer Aug 08 '18 at 17:49
  • 1
    "If you want to make sure it's somewhat more thread safe, use abort." It doesn't have any relationship with tread safety : it says only that either the thread that manipulate the current connection will have a consistent result : either progress to completion or throw an SQLException. – davidxxx Aug 08 '18 at 17:56
  • To me, the main difference seems to be Multi-Threading. In most code, a `Connection` will only be used by one thread at a time, and the `close()` is done in a `finally` block when the call stack is unwound. `abort()` talks about cancelling operations on the `Connection` being performed by other threads. – Andreas Aug 08 '18 at 17:57
  • How would you phrase it, @davidxxx? If I let a thread to progress to completion, or throw an exception I can catch, it /seems/ like it's well handled. Consider: setNetworkTimeout method: "This method is intended to address a rare but serious condition where network partitions can cause threads issuing JDBC calls to hang uninterruptedly in socket reads, until the OS TCP-TIMEOUT (typically 10 minutes). This method is related to the abort() method which provides an administrator thread a means to free any such threads in cases where the JDBC connection is accessible to the administrator thread. – J E Carter II Aug 08 '18 at 18:11
  • 1
    Your comment about thread-safety is incorrect. JDBC connections are required to be thread-safe by the JDBC specification, so `Connection.close()` is thread-safe, but in most drivers, if you are executing a long running query or update, the `Connection.close()` will either block until the statement is done, or maybe throw an exception as the connection is still 'busy'. An `abort` is for aborting (abruptly ending) the connection and making sure any other operations currently in progress (eg the other thread stuck in `executeQuery()` can continue as an exception is thrown that can be handled). – Mark Rotteveel Aug 08 '18 at 19:56
  • Cheers @MarkRotteveel. – J E Carter II Aug 08 '18 at 20:11
  • @MarkRotteveel Resurrecting this: I searched in the 4.3 specification (https://download.oracle.com/otn-pub/jcp/jdbc-4_3-mrel3-spec/jdbc4.3-fr-spec.pdf) for the word "thread" and the only three occurrences were in reference to the context classloader. Where is it defined that JDBC constructs must be thread-safe? While it makes sense, I can't find this requirement. – Laird Nelson Nov 07 '22 at 23:40
  • @LairdNelson I know it was present in some of the older JDBC specs, but it indeed no longer seems to be mentioned in more recent versions. However, most of the specified behaviour will require at least a modicum of thread-safety, especially when considering connection pooling, and the abort behaviour discussed here. See also https://stackoverflow.com/questions/1531073/is-java-sql-connection-thread-safe and the comments on the accepted answer. – Mark Rotteveel Nov 08 '22 at 08:41
  • @MarkRotteveel Thanks very much. I agree that there are implied thread safety semantics throughout the specification. (I just wish that specifications didn't imply things but rather stated them explicitly. :-) ) – Laird Nelson Nov 08 '22 at 16:15
  • 1
    @LairdNelson JDBC 1.20 (the first JDBC spec) had a whole chapter about it (e.g _"We require that all operations on all the java.sql objects be multi-thread safe and able to cope correctly with having several threads simultaneously calling the same object."_). This seems to have been removed when JDBC 3.0 consolidated JDBC 1.20, 2.0 Ext and 2.1. I guess it was done deliberately (this predates my membership of the EG, so I'm not sure), so maybe I should stop saying that connections are required to be thread-safe ;) (even though it is quite risky if they aren't). – Mark Rotteveel Nov 08 '22 at 16:27
  • 1
    @MarkRotteveel Right; one arbitrary example of what bothers me is that `PooledConnection`'s `getConnection` method's return value requirements are nonsensical without explicit thread safety requirements of _some_ sort. And yet they aren't really mentioned. Thanks again for the insights. – Laird Nelson Nov 08 '22 at 16:34
  • @LairdNelson It is probably because of another sentence in the JDBC 1.20 spec: _"In practice we expect that most of the JDBC objects will only be accessed in a single threaded way. However some multi-thread support is necessary, and our attempts in previous drafts to specify some classes as MT safe and some as MT unsafe appeared to be adding more confusion than light."_. That section also highlights that exact concurrency semantics may vary between drivers. – Mark Rotteveel Nov 08 '22 at 16:41