ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Clinton Begin" <clinton.be...@gmail.com>
Subject Re: Thread starvation - pool / Throttle issue?
Date Thu, 07 Aug 2008 04:56:43 GMT
It depends on the transaction manager and the datasource.

For example, with an "EXTERNAL" transaction manager and a user provided
connection (which overrides the datasource) like spring uses, Spring is
fully responsible for closing the connection.  The one exception might be
for lazily loaded objects, for which iBATIS may still control the lifecycle
of a connection, but that's somewhat separate and would behave as though it
were a JDBC transaction manager with a SIMPLE datasource (or whatever you
configure in SQLMap Config).

You never have to explicitly call close.  That's the iBATIS story.

*Generally Speaking*, the point of confusion I was responding to was your
assertion that a connection pool such as DBCP is responsible for closing
connections... which is technically what happens behind the scenes.  But
iBATIS aside, if you were using a connection pool like DBCP, you'd still
have to call close() on the connection to return it to the pool.

Cheers,
Clinton

On Wed, Aug 6, 2008 at 10:26 PM, Ian Zabel <ian@ezabel.com> wrote:

> Clinton,
>
> A bit confused here (new to ibatis)...
>
> The docs state: "By default, calling any execute method on SqlMapClient
> instance (e.g. queryForObject() or insert()) will auto-commit or
> auto-rollback.  This means that each call to any execution method will be a
> single unit of work. "
>
> Also, the code examples in the docs (p. 53) don't show any explicit close()
> calls.
>
> So, when using DBCP (retrieved with JDNI from Tomcat) without any Spring,
> and executing CRUD operations with auto-transactions, are you saying it is
> necessary to call close()?
>
> Thanks,
> Ian.
>
>
> On Aug 6, 2008, at 11:15 AM, Clinton Begin wrote:
>
>  Ah, if you're using Spring, then yes, it will take care of resource
>> allocation.  But your statement was: "but my understanding is that the DBCP
>> connection pool handles all that for me (?)", which is not the case.
>>
>> Clinton
>>
>> On Wed, Aug 6, 2008 at 7:57 AM, Brian Parkinson <parki@avaning.com>
>> wrote:
>> >
>> > HI Clinton:
>> >
>> > Have upgraded, and am refactoring some of my iBATIS code. You write:
>> >
>> > "Pools handle closing connections, but you still have to call .close (or
>> some higher level delegating method) to return the connection to the pool.
>>  The rules are always the same... if you open it / start it / retrieve it,
>> then you must close it / stop it / return it... "
>> >
>> > Below is an example Dao method implementation - my understanding (wrong,
>> it would appear) is that the SqlMapClientDaoSupport takes care of
>> ope/start/retrieve and close/stop/return.
>> >
>> > Do I need to enclose my call to getSqlMapClientTemplate().update(...) in
>> a try/catch with open/close?
>> >
>> > Thanks again - looks like homing in on the issue.
>> > Cheers,
>> >
>> > parki...
>> >
>> > --- x8 snip
>> >
>> > public class AlertDao extends SqlMapClientDaoSupport implements
>> IAlertDao
>> > {
>> >  public Acknowledgement acknowledgeAlert(String thermostatIdentifier,
>> String acknowledgeRef,
>> >   boolean remindMeLater) throws Exception
>> >  {
>> >   AlertEntry alertEntry = new AlertEntry(thermostatIdentifier,
>> acknowledgeRef);
>> >
>> >   getSqlMapClientTemplate().update("AlertMessage.updateByAlertEntry",
>> alertEntry);
>> >
>> >   Acknowledgement acknowledgedSet = new Acknowledgement();
>> >   acknowledgedSet.setThermostatIdentifier(thermostatIdentifier);
>> >   acknowledgedSet.setAcknowledgeRef(acknowledgeRef);
>> >   acknowledgedSet.setRemindMeLater(remindMeLater);
>> >
>> >   return acknowledgedSet;
>> >  }
>> >
>> > ________________________________
>> > From: Clinton Begin [mailto:clinton.begin@gmail.com]
>> > Sent: Wednesday, August 06, 2008 9:52 AM
>> > To: user-java@ibatis.apache.org
>> > Subject: Re: Thread starvation - pool / Throttle issue?
>> >
>> > Pools handle closing connections, but you still have to call .close (or
>> some higher level delegating method) to return the connection to the pool.
>>  The rules are always the same... if you open it / start it / retrieve it,
>> then you must close it / stop it / return it...
>> >
>> > That said, upgrade to 2.3.3.  Then you'll more easily find the true
>> root cause of your issue, as all of the Throttles have been removed for this
>> very reason.  You'll likely get a complaint about no more connections, or a
>> DB deadlock.
>> >
>> > Clinton
>> >
>> > On Wed, Aug 6, 2008 at 7:18 AM, Brian Parkinson <parki@avaning.com>
>> wrote:
>> >>
>> >> HI Nicholoz  - looked at that thread - thx.
>> >>
>> >> A key issue seems to be not closing connections, but my understanding
>> is that the DBCP connection pool handles all that for me (?).
>> >>
>> >> The Dao implementation is pretty simple - I'm not explicitly declaring
>> transations, since using Spring transaction stuff and so each Dao method
>> looks like below.
>> >>
>> >> Should I be explicitly handling transations stuff, and placing
>> everything inside try/catch/finally blocks? My understaniding was that the
>> Spring SqlMapClientDaoSupport did that for me.
>> >> public class AlertDao extends SqlMapClientDaoSupport implements
>> IAlertDao
>> >> {
>> >>  public Acknowledgement acknowledgeAlert(String thermostatIdentifier,
>> String acknowledgeRef,
>> >>   boolean remindMeLater) throws Exception
>> >>  {
>> >>   AlertEntry alertEntry = new AlertEntry(thermostatIdentifier,
>> acknowledgeRef);
>> >>
>> >>   getSqlMapClientTemplate().update("AlertMessage.updateByAlertEntry",
>> alertEntry);
>> >>
>> >>   Acknowledgement acknowledgedSet = new Acknowledgement();
>> >>   acknowledgedSet.setThermostatIdentifier(thermostatIdentifier);
>> >>   acknowledgedSet.setAcknowledgeRef(acknowledgeRef);
>> >>   acknowledgedSet.setRemindMeLater(remindMeLater);
>> >>
>> >>   return acknowledgedSet;
>> >>  }
>> >> ... ETC ...
>> >> }
>> >> The Spring declaration:
>> >>
>> >>  <bean id="txManager"
>> class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
>> >>   <property name="dataSource" ref="dataSource"/>
>> >>  </bean>
>> >>
>> >>  <tx:advice id="txAdvice" transaction-manager="txManager">
>> >>   <tx:attributes>
>> >>    <tx:method name="get*" read-only="true" />
>> >>    <tx:method name="*" />
>> >>   </tx:attributes>
>> >>  </tx:advice>
>> >>
>> >>  <aop:config>
>> >>   <aop:pointcut id="daoServiceOperation" expression="execution(*
>> com.ecobee.foundation.dao.ibatis.*.*(..))" />
>> >>   <aop:advisor advice-ref="txAdvice" pointcut-ref="daoServiceOperation"
>> />
>> >>  </aop:config>
>> >>
>> >> Appreciated - regards -
>> >>
>> >> parki...
>> >>
>> >> ________________________________
>> >> From: Nicholoz Koka Kiknadze [mailto:kiknadze@gmail.com]
>> >> Sent: Wednesday, August 06, 2008 8:56 AM
>> >> To: user-java@ibatis.apache.org
>> >> Subject: Re: Thread starvation - pool / Throttle issue?
>> >>
>> >> Have a look at this thread:
>> >>
>> >> http://www.mail-archive.com/user-java@ibatis.apache.org/msg11828.html
>> >>
>> >> Good luck
>> >>
>> >> On Wed, Aug 6, 2008 at 4:47 PM, Brian Parkinson <parki@avaning.com>
>> wrote:
>> >>>
>> >>> Hello:
>> >>>
>> >>> So, I have things up and running under Java and iBATIS, but running
>> into
>> >>> some starvation issue, and my server is locking up. When I dump
>> threads,
>> >>> I see a bunch that are waiting for the connnection pool (see output
#1
>> >>> below) and as well, a bunch that are waiting on Throttle.increment
>> (see
>> >>> output #2).
>> >>>
>> >>> Has anyone see anything similar?
>> >>>
>> >>> I am stumped right now - looking for ANY hints to help me track down
>> >>> (and fix :) what is going on - I don't know databases all that well,
>> so
>> >>> help appreciated greatly. First up, I'm going to upgrade to latest
>> >>> version of iBATIS, but thinking I might have something wrong in my
>> >>> thread pool setup.
>> >>>
>> >>> The pool setup:
>> >>>
>> >>>        <bean id="mapConfig"
>> >>> class="org.springframework.core.io.ClassPathResource">
>> >>>                <constructor-arg>
>> >>>
>> >>> <value>com/ecobee/foundation/dao/ibatis/SqlMapConfig.xml</value>
>> >>>                </constructor-arg>
>> >>>        </bean>
>> >>>
>> >>>        <bean id="dataSource"
>> >>> class="org.apache.commons.dbcp.BasicDataSource"
>> destroy-method="close">
>> >>>                <property name="driverClassName"
>> >>> value="com.mysql.jdbc.Driver" />
>> >>>                <property name="url" value="jdbc:mysql:///ecobee"
/>
>> >>>                <property name="username" value="XXX" />
>> >>>                <property name="password" value="XXX" />
>> >>>                <property name="initialSize" value="10" />
>> >>>                <property name="maxActive" value="100" />
>> >>>                <property name="maxIdle" value="10" />
>> >>>        </bean>
>> >>>
>> >>>        <bean id="sqlMapClient"
>> >>> class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
>> >>>                <property name="dataSource" ref="dataSource" />
>> >>>                <property name="configLocation" ref="mapConfig" />
>> >>>        </bean>
>> >>>
>> >>> I currently have no <settings> element in my SqlMapConfig.xml
file, so
>> >>> running with those defaults.
>> >>>
>> >>> Any help is greatly appreciated - I am mystified.
>> >>>
>> >>> I am using iBATIS 2.3.0.667 and commons dbcp 1.2.2, and running MySQL
>> >>> 5.0.32.
>> >>>
>> >>> Off to upgrade to latest iBATIS as a start -
>> >>>
>> >>> Cheers,
>> >>>
>> >>> parki...
>> >>>
>> >>> --- x8 snip
>> >>>
>> >>> Output #1:
>> >>>
>> >>> Thread: Thread[pool-1-thread-121,5,main]=
>> >>>  -- java.lang.Object.wait(Native Method)
>> >>>  -- java.lang.Object.wait(Object.java:474)
>> >>>  --
>> >>>
>> org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjec
>> >>> tPool.java:810)
>> >>>  --
>> >>>
>> org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSourc
>> >>> e.java:96)
>> >>>  --
>> >>>
>> org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.ja
>> >>> va:880)
>> >>>  --
>> >>>
>> org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin
>> >>> (DataSourceTransactionManager.java:200)
>> >>>  --
>> >>>
>> org.springframework.transaction.support.AbstractPlatformTransactionManag
>> >>> er.getTransaction(AbstractPlatformTransactionManager.java:377)
>> >>>  --
>> >>>
>> org.springframework.transaction.interceptor.TransactionAspectSupport.cre
>> >>> ateTransactionIfNecessary(TransactionAspectSupport.java:261)
>> >>>  --
>> >>>
>> org.springframework.transaction.interceptor.TransactionInterceptor.invok
>> >>> e(TransactionInterceptor.java:101)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Ref
>> >>> lectiveMethodInvocation.java:171)
>> >>>  --
>> >>>
>> org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(E
>> >>> xposeInvocationInterceptor.java:89)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Ref
>> >>> lectiveMethodInvocation.java:171)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAo
>> >>> pProxy.java:204)
>> >>>  -- $Proxy2.saveLogSet(Unknown Source)
>> >>>  --
>> >>>
>> com.ecobee.communicator.rest.restlet.LogRestlet.doPost(LogRestlet.java:7
>> >>> 6)
>> >>>  --
>> >>>
>> com.ecobee.communicator.rest.RestletManager.handleRequest(RestletManager
>> >>> .java:195)
>> >>>  --
>> >>>
>> com.ecobee.communicator.engine.EngineRequest.handleRequest(EngineRequest
>> >>> .java:112)
>> >>>  -- sun.reflect.GeneratedMethodAccessor338.invoke(Unknown Source)
>> >>>  --
>> >>>
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
>> >>> Impl.java:25)
>> >>>  -- java.lang.reflect.Method.invoke(Method.java:585)
>> >>>  --
>> >>>
>> com.whatevernot.engine.standard.StateRunnable.run(StateRunnable.java:56)
>> >>>  --
>> >>>
>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecuto
>> >>> r.java:650)
>> >>>  --
>> >>>
>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.ja
>> >>> va:675)
>> >>>  -- java.lang.Thread.run(Thread.java:595)
>> >>>
>> >>> Output #2:
>> >>>
>> >>> Thread: Thread[pool-1-thread-613,5,main]=
>> >>>  -- java.lang.Object.wait(Native Method)
>> >>>  -- java.lang.Object.wait(Object.java:474)
>> >>>  -- com.ibatis.common.util.Throttle.increment(Throttle.java:70)
>> >>>  -- com.ibatis.common.util.ThrottledPool.pop(ThrottledPool.java:57)
>> >>>  --
>> >>>
>> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.popSession(SqlMapEx
>> >>> ecutorDelegate.java:933)
>> >>>  --
>> >>>
>> com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.<init>(SqlMapSessionImpl
>> >>> .java:51)
>> >>>  --
>> >>>
>> com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.getLocalSqlMapSession(Sql
>> >>> MapClientImpl.java:259)
>> >>>  --
>> >>>
>> com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.startBatch(SqlMapClientIm
>> >>> pl.java:161)
>> >>>  -- com.ecobee.foundation.dao.ibatis.LogDao.saveLogSet(LogDao.java:22)
>> >>>  -- sun.reflect.GeneratedMethodAccessor341.invoke(Unknown Source)
>> >>>  --
>> >>>
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
>> >>> Impl.java:25)
>> >>>  -- java.lang.reflect.Method.invoke(Method.java:585)
>> >>>  --
>> >>>
>> org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(
>> >>> AopUtils.java:301)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinp
>> >>> oint(ReflectiveMethodInvocation.java:182)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Ref
>> >>> lectiveMethodInvocation.java:149)
>> >>>  --
>> >>>
>> org.springframework.transaction.interceptor.TransactionInterceptor.invok
>> >>> e(TransactionInterceptor.java:106)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Ref
>> >>> lectiveMethodInvocation.java:171)
>> >>>  --
>> >>>
>> org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(E
>> >>> xposeInvocationInterceptor.java:89)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Ref
>> >>> lectiveMethodInvocation.java:171)
>> >>>  --
>> >>>
>> org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAo
>> >>> pProxy.java:204)
>> >>>  -- $Proxy2.saveLogSet(Unknown Source)
>> >>>  --
>> >>>
>> com.ecobee.communicator.rest.restlet.LogRestlet.doPost(LogRestlet.java:7
>> >>> 6)
>> >>>  --
>> >>>
>> com.ecobee.communicator.rest.RestletManager.handleRequest(RestletManager
>> >>> .java:195)
>> >>>  --
>> >>>
>> com.ecobee.communicator.engine.EngineRequest.handleRequest(EngineRequest
>> >>> .java:112)
>> >>>  -- sun.reflect.GeneratedMethodAccessor338.invoke(Unknown Source)
>> >>>  --
>> >>>
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
>> >>> Impl.java:25)
>> >>>  -- java.lang.reflect.Method.invoke(Method.java:585)
>> >>>  --
>> >>>
>> com.whatevernot.engine.standard.StateRunnable.run(StateRunnable.java:56)
>> >>>  --
>> >>>
>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecuto
>> >>> r.java:650)
>> >>>  --
>> >>>
>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.ja
>> >>> va:675)
>> >>>  -- java.lang.Thread.run(Thread.java:595)
>> >>
>> >
>>
>>
>

Mime
View raw message