ibatis-user-cs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Shane Boyer <boy...@frontiernet.net>
Subject DataAccess, multiple contexts and session on the same thread
Date Tue, 06 Mar 2007 21:39:15 GMT
Hello,
I've been using iBATIS for a couple of months now, it's a nice framework 
so thanks for the hard work. I'm currently using 1.5.1 + 1.8.1 of the 
mapper/access layer, but verified the following works the same in the 
newest beta versions.   I've run into what appears to be a bug in the 
DataAccess session handling setup, but if I'm approaching this 
incorrectly I'm looking for suggestions.  The basic thing I want to do 
is have an independent connection that I can use to log status and 
errors to a database without being affected by the success/fail of any 
existing transaction in progress, and without having to affect the code 
outside of the database logger with respect to transactions.  The most 
obvious way I see to do this with support from iBATIS is to define a 
separate Dao context for logging.  This is where I ran into a problem.

If I have multiple DAO contexts defined and attempt to open or start a 
transaction on more than one context on the same thread  I am receiving 
the "session already option / transaction already started" exception.  I 
setup a test similar to the MultipleDAOTest in the iBATIS test cases 
like so:
       [Test]
       public void TestMultipleDAO()
       {
           DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
           builder.Configure("dao.config");

           IDaoManager mgr1 = DaoManager.GetInstance("Context1");
           IDaoManager mgr2 = DaoManager.GetInstance("Context2");
           IPatronDAO pDao = mgr1[typeof(IPatronDAO)] as IPatronDAO;
           ILogDAO lDao = mgr2[typeof(ILogDAO)] as ILogDAO;

           mgr1.OpenConnection();
           mgr2.OpenConnection();    <--- this is where the exception is 
thrown
           ...
           mgr1.CloseConnection();
           mgr2.CloseConnection();
       }

I traced this into the iBATIS source, and see that when the 
DomDaoManagerBuilder creates a DaoManager instance 
(DaoManager.NewInstance), the internal DaoManager constructor is 
invoked, which immediately calls SessionStoreFactory with the DaoManager 
id to create a session store.  The problem appears to be that the call 
to the SessionStoreFactory will always receive an empty string for id of 
the Dao Context, since DomDaoManagerBuilder::GetContexts() doesn't 
actually set the context id until after DaoManager.NewInstance() 
returns.  As a result, sessions for all contexts on the same thread are 
keyed on the default string _IBATIS_LOCAL_DAOSESSION_ from 
AbstractSessionStore, which I confirmed through VS2005 debugging.  As 
soon as you create one session (openconnection or begintransaction), all 
contexts' LocalDaoSession reference this session because the sessionName 
is the same for all.

DataMapper does not appear have this problem because in constructing a 
mapper the id is set during construction, prior to calling the session 
store factory.

My hope is that I'm doing something wrong, and would welcome the 
assistance.
Thank you, Shane

Mime
View raw message