You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Louis Letourneau (JIRA)" <ib...@incubator.apache.org> on 2005/08/11 23:56:54 UTC

[jira] Created: (IBATISNET-102) Calling OpenConnection on a DaoManager in different threads causes an Exception

Calling OpenConnection on a DaoManager in different threads causes an Exception
-------------------------------------------------------------------------------

         Key: IBATISNET-102
         URL: http://issues.apache.org/jira/browse/IBATISNET-102
     Project: iBatis for .NET
        Type: Bug
  Components: DataAccess  
    Versions: DataAccess 1.6.0, DataAccess 1.6.1    
 Environment: windows xp sp2, .Net 1.1 sp1
    Reporter: Louis Letourneau


Opening many (different)connections each in a seperate thread (as would occur in a web application) for one instance of a DaoManager causes connection already opened exceptions (or calling CloseConnection in the same circumstances causes connection already closed exceptions) . It's as if the new sessions don't get created individually for each thread...

I took the liberty of checking the source code of the DataAccess component, and the variable _localSqlMapSession in WindowSessionContainer.cs should be static. If it's not the ThreadStatic attribute will have no effect and every thread will have the same session (as in my case).
(The java ThreadLocal object can be used on a non-static field. The ThreadStatic attribute cannot. The compiler ignores the attribute on non-static fields).

Exception:
Got: IBatisNet.DataAccess.Exceptions.DataAccessException: DaoManager could not invoke OpenConnection(). A connection is already started. Call CloseConnection first.

I think that if you wish to have the same behaviour as the java dao implementation (having multiple DaoManager instances that each have different sessions per thread) adding the static modifier to the ThreadStatic field will not fix the issue in WindowSessionContainer.cs.

Instead of the static ThreadStatic field(which will be shared by every WindowSessionContainer in a given thread), maybe a hashtable instance that has the current daomanager name as key and the session as value would work.

ie(WindowSessionContainer.cs) Replace:
------------------------------------------------
[ThreadStatic] 
private 'static' IDalSession _localSqlMapSession = null; // currently missing the static modifier here

public IDalSession LocalSession
{
	get
	{
		return _localSqlMapSession;
	}
}

public void Store(IDalSession session)
{
	_localSqlMapSession = session;
}
------------------------------------------------
by
------------------------------------------------
[ThreadStatic] 
private static IDictionary _localSqlMapSessions; // can't initialize ThreadStatic variables.
private static Object _mutex = new Object();
private string _daoManagerName;

public WindowSessionContainer(string daoManagerName) {
	lock(_mutex) {
		if(_localSqlMapSessions == null)
			_localSqlMapSessions = new Hashtable();
	}
	_daoManagerName = daoManagerName;
}

public IDalSession LocalSession
{
	get
	{
		return _localSqlMapSessions[_daoManagerName];
	}
}

public void Store(IDalSession session)
{
	_localSqlMapSessions[_daoManagerName] = session;
}
------------------------------------------------

This way, for a given thread, every WindowSessionContainer will share the _localSqlMapSessions, but since there is one WindowSessionContainer per DaoManager, the IDalSession will be unique by thread+DaoManager instance. And as a bonus, when the thread dies, the resources will be cleaned up.


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Closed: (IBATISNET-102) Calling OpenConnection on a DaoManager in different threads causes an Exception

Posted by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org>.
     [ http://issues.apache.org/jira/browse/IBATISNET-102?page=all ]
     
Gilles Bayon closed IBATISNET-102:
----------------------------------

    Fix Version: DataAccess 1.7
     Resolution: Fixed
      Assign To: Gilles Bayon

In SVN

> Calling OpenConnection on a DaoManager in different threads causes an Exception
> -------------------------------------------------------------------------------
>
>          Key: IBATISNET-102
>          URL: http://issues.apache.org/jira/browse/IBATISNET-102
>      Project: iBatis for .NET
>         Type: Bug
>   Components: DataAccess
>     Versions: DataAccess 1.6.0, DataAccess 1.6.1
>  Environment: windows xp sp2, .Net 1.1 sp1
>     Reporter: Louis Letourneau
>     Assignee: Gilles Bayon
>      Fix For: DataAccess 1.7

>
> Opening many (different)connections each in a seperate thread (as would occur in a web application) for one instance of a DaoManager causes connection already opened exceptions (or calling CloseConnection in the same circumstances causes connection already closed exceptions) . It's as if the new sessions don't get created individually for each thread...
> I took the liberty of checking the source code of the DataAccess component, and the variable _localSqlMapSession in WindowSessionContainer.cs should be static. If it's not the ThreadStatic attribute will have no effect and every thread will have the same session (as in my case).
> (The java ThreadLocal object can be used on a non-static field. The ThreadStatic attribute cannot. The compiler ignores the attribute on non-static fields).
> Exception:
> Got: IBatisNet.DataAccess.Exceptions.DataAccessException: DaoManager could not invoke OpenConnection(). A connection is already started. Call CloseConnection first.
> I think that if you wish to have the same behaviour as the java dao implementation (having multiple DaoManager instances that each have different sessions per thread) adding the static modifier to the ThreadStatic field will not fix the issue in WindowSessionContainer.cs.
> Instead of the static ThreadStatic field(which will be shared by every WindowSessionContainer in a given thread), maybe a hashtable instance that has the current daomanager name as key and the session as value would work.
> ie(WindowSessionContainer.cs) Replace:
> ------------------------------------------------
> [ThreadStatic] 
> private 'static' IDalSession _localSqlMapSession = null; // currently missing the static modifier here
> public IDalSession LocalSession
> {
> 	get
> 	{
> 		return _localSqlMapSession;
> 	}
> }
> public void Store(IDalSession session)
> {
> 	_localSqlMapSession = session;
> }
> ------------------------------------------------
> by
> ------------------------------------------------
> [ThreadStatic] 
> private static IDictionary _localSqlMapSessions; // can't initialize ThreadStatic variables.
> private static Object _mutex = new Object();
> private string _daoManagerName;
> public WindowSessionContainer(string daoManagerName) {
> 	lock(_mutex) {
> 		if(_localSqlMapSessions == null)
> 			_localSqlMapSessions = new Hashtable();
> 	}
> 	_daoManagerName = daoManagerName;
> }
> public IDalSession LocalSession
> {
> 	get
> 	{
> 		return _localSqlMapSessions[_daoManagerName];
> 	}
> }
> public void Store(IDalSession session)
> {
> 	_localSqlMapSessions[_daoManagerName] = session;
> }
> ------------------------------------------------
> This way, for a given thread, every WindowSessionContainer will share the _localSqlMapSessions, but since there is one WindowSessionContainer per DaoManager, the IDalSession will be unique by thread+DaoManager instance. And as a bonus, when the thread dies, the resources will be cleaned up.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira