java - Proper Implementation of JDBC Multithreading with JNDI -


i'm working on project i'm doing lot of queries , time consideration want try , implement jdbc multithreading. i'm not sure proper way is.

here's first draft implementation:

spring datasource bean:

private datasource ds; @resource(name="jdbc") public void setdatasource(datasource ds) {     this.ds = ds; } 

initialization method:

  public void checkusersmulti(list<user> users) throws exception {     if(users!= null || users.size() != 0) {         executorservice executorservice = executors.newfixedthreadpool(20);         queue<user> queue = new concurrentlinkedqueue<>();         queue.addall(users);         (useruser: users) {             executorservice.submit(new processuser(queue));         }         executorservice.shutdown();         try {             executorservice.awaittermination(1, timeunit.hours);         } catch (interruptedexception e) {             e.printstacktrace();         }      } } 

runnable class:

class processuser implements runnable {     private final queue<user> queue;      public processuser(queue<user> queue) {         this.queue = queue;     }      public void run() {         try {             connection conn = ds.getconnection();             user user = null;             while((user = queue.poll()) != null) {                 userdao.getuser(user , conn));             }             dbutils.closequietly(conn);         } catch (exception e) {             e.printstacktrace();         }     } } 

user dao method:

public user retrieveuser(user user, connection conn)  {     preparedstatement st = null;     resultset rs = null;     try {         string sql = "select firstname, lastname users id= ?;          st = conn.preparestatement(sql);         st.setstring(1, user.getid());         rs = st.executequery();          while(rs.next()) {             user.setfirstname(rs.getstring("firstname"));             user.setlastname(rs.getstring("lastname"));         }     } catch (exception e) {         return null;     }     {         dbutils.closequietly(rs);         dbutils.closequietly(st);     }     return user; } 

update: tomcat jndi connection pool settings:

 <resource     name="jdbc"     auth="container"     type="javax.sql.datasource"     maxtotal ="25"     maxidle="30"     maxwaitmillis ="10000"     driverclassname="***vendor driver***"     url="***valid url"     username="***valid username***"     password="***valid password***" /> 

however, getting error occasionally:

java.sql.sqlexception: cannot connection, pool error timeout waiting idle object

but process still completes expected - may in jndi settings. bigger concern if "correct" way implement this. assumed best hold onto connection object don't have re-initialized.

there couple of issues code, importantly, not sure this:

   public void checkusersmulti(list<user> users) throws exception {     if(users!= null || users.size() != 0) {         executorservice executorservice = executors.newfixedthreadpool(20);         queue<user> queue = new concurrentlinkedqueue<>();         queue.addall(users);         (useruser: users) {             executorservice.submit(new processuser(queue));         }         executorservice.shutdown();         try {             executorservice.awaittermination(1, timeunit.hours);         } catch (interruptedexception e) {             e.printstacktrace();         }      } } 

is supposed do. if understand correctly, create queue of users in it, , submit executor many times there users. mean that:

  • you limited in terms of number of users can process, because queue can not grow indefinitely (which @sabit khan worried about)

  • you have run runnable @ least once each user, although unless runnables exit because of error, first 20 keep running until queue empty, , remaining invoked, see queue empty, , exit.

you should limit number of parallel processes starting. have thread pool of 20 though, there should never more 20 concurrent connections, if close connections properly. don't mention other exceptions, this:

    try {         connection conn = ds.getconnection();         user user = null;         while((user = queue.poll()) != null) {             userdao.getuser(user , conn));         }         dbutils.closequietly(conn);     } catch (exception e) {         e.printstacktrace();     } 

should be:

    connection conn = null;     try {         conn = ds.getconnection();         user user = null;         while((user = queue.poll()) != null) {             userdao.getuser(user , conn));         }     } catch (exception e) {         e.printstacktrace();     } {         dbutils.closequietly(conn);     } 

just make sure connection closed in situation.

also, since you're apparently using underlying connection pool, might want try getting , returning connections every single time.

as actual question: way you're doing means first twenty runnables try connections , hold them long time. if pool configured use provide less connections (let's 15), happen, since first 15 connection, next 5 workers continously run runnable, try, fail, exit. or of use 20 connections in pool, might leaking connections because you're not closing them described above.


Comments

Popular posts from this blog

SVG stroke-linecap doesn't work for circles in Firefox? -

routes - Laravel 4 Wildcard Routing to Different Controllers -

cross browser - XSLT namespace-alias Not Working in Firefox or Chrome -