Thread Local in Session

Hi you all,

I've been trying to understand wether one should use ThreadLocal when working with session objects.

I read this this:

http://nikhilb020875.wordpress.com/tag/session/

But this didnt help me either:

Supposed I create a Database Class, that helps run database related code, that has a thread scoped variable (i.e., a ThreadLocal), which is static, this means that the same connection is going to be use across the context application... wouldn磘 it be better to have one conn per session?

publicclass Database

{

//////////////////////////////////////////////////////////////

// Class objects

//////////////////////////////////////////////////////////////

privatestatic ThreadLocal<Database> instance =new ThreadLocal<Database>();

//////////////////////////////////////////////////////////////

// Class constructors

//////////////////////////////////////////////////////////////

private Database(){}

//////////////////////////////////////////////////////////////

// Class functions

//////////////////////////////////////////////////////////////

privateint openConn(){}

//////////////////////////////////////////////////////////////

publicboolean isOpen(){}

//////////////////////////////////////////////////////////////

publicvoid setTransaction(){}

//////////////////////////////////////////////////////////////

publicvoid commit(){}

//////////////////////////////////////////////////////////////

publicvoid roolback(){}

//////////////////////////////////////////////////////////////

public Boolean runStatement(String pStrStmt, Object[] values){}

//////////////////////////////////////////////////////////////

privatevoid setParameters(Object[] values, PreparedStatement pstmt){}

//////////////////////////////////////////////////////////////

publicboolean runStatementUpdate(String pStrStmt){}

//////////////////////////////////////////////////////////////

publicboolean runStatementInsert(String pStrStmt){}

//////////////////////////////////////////////////////////////

publicint runStatementInsert(String pStrStmt,boolean returnIdentity){}

//////////////////////////////////////////////////////////////

publicint runStatementInsert(String pStrStmt, Object[] values){}

//////////////////////////////////////////////////////////////

public ResultSet runStatementQuery(String pStrStmt){}

//////////////////////////////////////////////////////////////

public ResultSet runStatementQuery(String pStrStmt, Object[] values){}

//////////////////////////////////////////////////////////////

publicvoid closeConn(){}

//////////////////////////////////////////////////////////////

private Boolean runStatement(String pStrStmt){}

//////////////////////////////////////////////////////////////

publicstatic Database getInstance(){

if (instance.get() ==null){

Database database =new Database();

instance.set(database);

}

return instance.get();

}

}

This is one class that I am using, does it make any sense for this class to use threadLocal ?

I know its not good to pass a connection as an arg to classes that not extend the HttpSession, but to do the otherwise is having only one connection per context..

Any help is more then welcome ;)

Thanks,

MeTitus

[6600 byte] By [Me_Titusa] at [2007-11-26 18:09:31]
# 1

My gut instinct says no, simply because in a multi-threaded Servlet-type application, you get one thread per request (and hence one ThreadLocal) whereas session data spans requests. Let's say the Servlet container has a pool of 10 threads, how can you guarantee the same thread that serviced a previous response (and hence its ThreadLocal) will be available or used on a subsequent request?

- Saish

Saisha at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

Hi Saish, thanks for you help, but there are a few more things I need to know,

Does your answer:

> My gut instinct says no

refers to this

> Supposed I create a Database Class, that helps run database

> related code, that has a thread scoped variable (i.e., a ThreadLocal),

> which is static, this means that the same connection is going to be

> use across the context application... wouldn磘 it be better to have one

> conn per session?

If I understood it well, you are saying that if I use ThreadLocal and the server is processing 10 requests then I will have 10 connections, right?

Many thanks,

MeTitus

Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3
You will have one connection per thread. You would probably be better off using connection pooling. For example, if you are using JBoss it has excellent connection pooling built in.
jleecha at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

I've been digging about this topic and all I could find was that an JNDI offers what a ThreadLocal would offer in this case.

For what I read, one of the benefits people say, about using ThreadLocal is that it makes it useless to pass a connection as a parameter to other classes, but then again JNDI offers us that already. One think that I have been wondering about too, is how a JNDI resource which provides a JDBC resource works...

it works as a JDBC connection pool which is managed by the container right? rather then a single connection...

In any case If I wanted to have a Database object per request rather than per Session I could create a new Database object and store it in the request object... so I don't see any benefits if using a ThreadLocal here... If I undestood it well there is only one threadLocal per request so is it worth wasting it with some functionality already providaded by the JNDI...

Thanks,

MeTitus

Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5

Hi jleech,

thanks for your post...

I normally use JBoss, but since I am quite new to web programming with java, there are a few things I need to undesrtand, and one of those is about the ThreadLocal class. I have use a JDBC conn mapped to a JNDI resource, but I didn't know how really it worked...

Thanks for your help,

MeTitus

Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

This is some of the methods I have implemented in my class, so in this case is it worth to use ThreadLocal here? Sorry to ask the same question again and again but I really would like to understand how this works best.

private static ThreadLocal<Database> instance = new ThreadLocal<Database>();

private Database() {

try {

Context ctx = new InitialContext();

ds = (DataSource) ctx.lookup("java:MekwaDS");

} catch (NamingException e) {

log.error(e, e);

}

}

private int openConn() {

try {

if (ds == null) {

Class.forName("com.mysql.jdbc.Driver");

this.objConn = DriverManager.getConnection(this.dbUrl, this.dbUser, this.dbPass);

} else if (objConn == null || objConn.isClosed()) {

this.objConn = ds.getConnection();

this.objConn.setAutoCommit(false);

}

} catch (ClassNotFoundException ex) {

log.error(ex, ex);

throw new RuntimeException("Could not open connection to database!");

} catch (SQLException ex) {

log.error(ex, ex);

throw new RuntimeException("Could not open connection to database!");

}

return 0;

}

public static Database getInstance() {

if (instance.get() == null) {

Database database = new Database();

instance.set(database);

}

return instance.get();

Thanks,

MeTitus

Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

I've been reading this resource as well,

http://www-128.ibm.com/developerworks/java/library/j-threads3.html

what I am thinking now is that at some point, maybe before JBoss and others containers, which provide Connection Pooling, and also for J2SE desktop based applications, ThreadLocal was a very wise choice, but right now is not that usefull, at least in this regarding.

What do you guys think.

MeTitus

Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8
Well this last told me what I need to hear... http://www.antonioshome.net/blog/pivot/entry.php?id=30MeTitus
Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9
Pooling, generally, can improve performance and utilization for scarce resources (ala database connections). It is not a panacea, but try out Jakarta's database connection pool (DBCP) at jakarta.apache.org (under the Commons project).- Saish
Saisha at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10
Doesn't a container provided that as well? I thought that when using a database connection thru a JNDI resource, the container would manage a connection pooling automatically.Thanks Saish,MeTitus
Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11

It might under the hood pool DataSource instances. However, there are two reasons not to do so. First, containers try to be all things to all people. Better to use software designed to one job well. Second, you may inadvertently tie yourself to a specific container vendor. By using a third-party and open source API, you can be container agnostic.

- Saihs

Saisha at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 12
Thank you very much for all your help Saish ;)MeTitus
Me_Titusa at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 13
Best of luck. And my pleasure. :^)- Saish
Saisha at 2007-7-9 5:41:30 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...