Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing a jdbc "Connection" across threads

I have a main thread that runs periodically. It opens a connection, with setAutoCommit(false), and is passed as reference to few child threads to do various database read/write operations. A reasonably good number of operations are performed in the child threads. After all the child threads had completed their db operations, the main thread commits the transaction with the opened connection. Kindly note that I run the threads inside the ExecutorService. My question, is it advisable to share a connection across threads? If "yes" see if the below code is rightly implementing it. If "no", what are other way to perform a transaction in multi-threaded scenario? comments/advise/a-new-idea are welcome. pseudo code...

Connection con = getPrimaryDatabaseConnection();
// let me decide whether to commit or rollback
con.setAutoCommit(false);

ExecutorService executorService = getExecutor();
// connection is sent as param to the class constructor/set-method
// the jobs uses the provided connection to do the db operation
Callable jobs[] = getJobs(con); 
List futures = new ArrayList();
// note: generics are not mentioned just to keep this simple
for(Callable job:jobs) {
    futures.add(executorService.submit(job));
}
executorService.shutdown();
// wait till the jobs complete
while (!executorService.isTerminated()) {
  ;
}

List result = ...;
for (Future future : futures) {
    try {
       results.add(future.get());
    } catch (InterruptedException e) {
      try {
        // a jobs has failed, we will rollback the transaction and throw exception
        connection.rollback();
        result  = null;
        throw SomeException();
      } catch(Exception e) {
       // exception
      } finally {
         try {
           connection.close();
         } catch(Exception e) {//nothing to do}
      }    
   }
}
// all the jobs completed successfully!
try {
  // some other checks
  connection.commit();
  return results;
} finally {
  try {
      connection.close();
  } catch(Exception e){//nothing to do}
}
like image 204
Vijay Veeraraghavan Avatar asked Sep 19 '13 14:09

Vijay Veeraraghavan


People also ask

Are JDBC connections thread-safe?

All public Toolbox JDBC objects are threadsafe and can be shared between multiple threads.

Can multiple threads use the same DB connection?

No. Of course not. Each thread needs its own connection.

Is PreparedStatement thread-safe?

You should prepare only once, and cache the PreparedStatement in your application (it is thread-safe). If you call prepare multiple times with the same query string, the driver will log a warning. If you execute a query only once, a prepared statement is inefficient because it requires two roundtrips.

Are databases thread-safe?

The Android uses java locking mechanism to keep SQLite database access serialized. So, if multiple thread have one db instance, it always calls to the database in serialized manner and of course database is thread-safe.


2 Answers

I wouldn't recommend you to share connection between threads, as operations with connection is quite slow and overall performance of you application may harm.

I would rather suggest you to use Apache Connections Pool and provide separate connection to each thread.

like image 95
nkukhar Avatar answered Oct 12 '22 23:10

nkukhar


You could create a proxy class that holds the JDBC connection and gives synchronized access to it. The threads should never directly access the connection.

Depending on the use and the operations you provide you could use synchronized methods, or lock on objects if the proxy needs to be locked till he leaves a certain state.


For those not familiar with the proxy design pattern. Here the wiki article. The basic idea is that the proxy instance hides another object, but offers the same functionality.

like image 34
mike Avatar answered Oct 13 '22 00:10

mike