mybatis caching always hangs in "Unsafe.park". Any tips?

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

mybatis caching always hangs in "Unsafe.park". Any tips?

Simon
Problem: If we enable caching, our app hangs within 30 seconds.  If we
disable it, it works perfectly.

We are using oracle 11g, and mybatis 3.0.1

We have game engine which manages client games starting and ending
(think slots game with jackpots).

We have a test harness which calls startGame and endGame in a loop for
a number of test players, one player per thread.

If we use 1 thread, all is good, we can run say 10,000 games for 1
player.

If we have mutliple threads, and mybatis caching enabled, then very
soon (<10 games), the entire engine hangs.  We thought it was the DB,
but our expert Oracle DBA says there are no deadlocks, and all the
sessions are idle in that they have sent the results back to mybatis
and are waiting for the next sql command.

Doing a stack dump of the hung engine, I can see that 18 of the 20
threads are stuck in "Unsafe.park":

Thread [Thread-4] (Suspended)
        Unsafe.park(boolean, long) line: not available [native method]
        LockSupport.park(Object) line: 158
        ReentrantReadWriteLock
$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line:
747
        ReentrantReadWriteLock
$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int) line:
877
        ReentrantReadWriteLock
$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int) line:
1197
        ReentrantReadWriteLock$ReadLock.lock() line: 594
        CachingExecutor.query(MappedStatement, Object, RowBounds,
ResultHandler) line: 52
        DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
        DefaultSqlSession.selectList(String, Object) line: 53
        DefaultSqlSession.selectOne(String, Object) line: 38
        MapperMethod.execute(Object[]) line: 66
        MapperProxy.invoke(Object, Method, Object[]) line: 35
        $Proxy13.selectJackpotBalanceForGame(long) line: not available
        JackpotService.selectJackpotBalanceForGame(long) line: 52
        JackpotService.selectJackpotBalanceForPlayergame(long) line: 302
        EndGame.doAction(APIProperties) line: 73
        ApiServlet.execFunction(APIProperties) line: 148
        DirectApiTester.run(APIProperties) line: 27
        TestMain.runSequence(Tester, int) line: 202
        NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
        NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
        DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
        Method.invoke(Object, Object...) line: 597
        TestMain$1.run() line: 47
        Thread.run() line: 619

The other two threads were doing this:

Thread [Thread-14] (Suspended)
        SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int)
line: not available [native method]
        SocketInputStream.read(byte[], int, int) line: 129
        DataPacket(Packet).receive() line: 240
        DataPacket.receive() line: 92
        NetInputStream.getNextPacket() line: 172
        NetInputStream.read(byte[], int, int) line: 117
        NetInputStream.read(byte[]) line: 92
        NetInputStream.read() line: 77
        T4CMAREngine.unmarshalUB1() line: 1034
        T4CMAREngine.unmarshalSB1() line: 1010
        T4C8Oall.receive() line: 588
        T4CPreparedStatement.doOall8(boolean, boolean, boolean, boolean)
line: 194
        T4CPreparedStatement.executeForDescribe() line: 791
        T4CPreparedStatement.executeMaybeDescribe() line: 866
        T4CPreparedStatement(OracleStatement).doExecuteWithTimeout() line:
1186
        T4CPreparedStatement(OraclePreparedStatement).executeInternal() line:
3387
        T4CPreparedStatement(OraclePreparedStatement).execute() line: 3488
        OraclePreparedStatementWrapper.execute() line: 1374
        GeneratedMethodAccessor19.invoke(Object, Object[]) line: not
available
        DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
        Method.invoke(Object, Object...) line: 597
        PreparedStatementLogger.invoke(Object, Method, Object[]) line: 45
        $Proxy2.execute() line: not available
        PreparedStatementHandler.query(Statement, ResultHandler) line: 39
        RoutingStatementHandler.query(Statement, ResultHandler) line: 55
        SimpleExecutor.doQuery(MappedStatement, Object, RowBounds,
ResultHandler) line: 41
        SimpleExecutor(BaseExecutor).query(MappedStatement, Object,
RowBounds, ResultHandler) line: 94
        CachingExecutor.query(MappedStatement, Object, RowBounds,
ResultHandler) line: 65
        DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
        DefaultSqlSession.selectList(String, Object) line: 53
        DefaultSqlSession.selectOne(String, Object) line: 38
        MapperMethod.execute(Object[]) line: 66
        MapperProxy.invoke(Object, Method, Object[]) line: 35
        $Proxy13.getLock(long) line: not available
        JackpotService.win(SqlSession, long, long) line: 264
        JackpotWinlineService.settle(SqlSession, Winline, PlayerGame,
Boolean) line: 112
        WinlineService.settle(SqlSession, Winline, PlayerGame, Boolean) line:
170
        WinnableService.settle(SqlSession, Winnable, PlayerGame, Boolean)
line: 128
        PlayerGameService.endGame(long, Session, PlayerGame, Game, String[])
line: 307
        MasterGameController.endGame(long, String, long, String[]) line: 47
        EndGame.doAction(APIProperties) line: 59
        ApiServlet.execFunction(APIProperties) line: 148
        DirectApiTester.run(APIProperties) line: 27
        TestMain.runSequence(Tester, int) line: 202
        NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
        NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
        DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
        Method.invoke(Object, Object...) line: 597
        TestMain$1.run() line: 47
        Thread.run() line: 619

The problem occurs around the only shared resource, the jackpot.  We
get a lock on it if a jackpot is won (1in4 chance for testing), so
only one person can win it, but dont update the actual jackpot table
at all during out tests (we insert transactions against the jackpots
pot account).

Here is the jackpotMapper.xml. Notice all the balance selects have
useCache="false".  the balance functions are just conveinience
methods, we could have got the balance from the pot for the
jackpot.poid in the pot mapper (which also have useCache="false").

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
                "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.skillkash.ge.mapper.JackpotMapper">


        <cache eviction="FIFO" flushInterval="60000" size="512"/>


        <insert id="insert">
:removed for brevity.
        </insert>

        <select id="select" resultType="com.skillkash.ge.beans.JackpotBean">
                select * from Jackpot
                where id =
                #{value}
        </select>

        <resultMap id="selectWithPotsResultMap"
type="com.skillkash.ge.beans.JackpotBean">
                <association property="pot" column="potid"
                        javaType="com.skillkash.ge.beans.Pot"
select="com.skillkash.ge.mapper.PotMapper.select" />
                <association property="pendingpot" column="pendingpotid"
                        javaType="com.skillkash.ge.beans.Pot"
select="com.skillkash.ge.mapper.PotMapper.select" />
                <association property="seedpot" column="seedpotid"
                        javaType="com.skillkash.ge.beans.Pot"
select="com.skillkash.ge.mapper.PotMapper.select" />
        </resultMap>

        <select id="selectWithPots" resultMap="selectWithPotsResultMap">
                select * from Jackpot
                where id = #{value}
        </select>


        <select id="selectAll" resultMap="selectWithPotsResultMap">
                select * from Jackpot
        </select>

        <select id="selectActive" resultMap="selectWithPotsResultMap">
                select unique j.* from
                Jackpot j, game g
                where g.jackpotid = j.id
                and G.DELETEDYN = 0
        </select>

        <select id="selectJackpotBalanceForGame" resultType="BigDecimal"
                useCache="false">
                select
                pot.balance
                from pot, game, jackpot
                where
                pot.id =
                jackpot.potid
                and
                game.jackpotid = jackpot.id
                and game.id = #{Value}
        </select>

        <select id="selectBalanceForJackpot" resultType="BigDecimal"
                useCache="false">
                select
                pot.balance
                from pot, jackpot
                where
                pot.id = jackpot.potid
                and jackpot.id
                = #{Value}
        </select>

        <select id="selectSeedBalanceForJackpot" resultType="BigDecimal"
                useCache="false">
                select
                pot.balance
                from pot, jackpot
                where
                pot.id =
                jackpot.seedpotid
                and
                jackpot.id = #{Value}
        </select>

        <select id="getLock" resultType="Long" useCache="false">
                select id
                from jackpot
                where
                id =
                #{Value}
                for update
        </select>

        <select id="selectJackpotForWinline"
resultMap="selectWithPotsResultMap">
                select jp.*
                from
                jackpot jp, jackpotwinline jpwl
                where
                jp.id = jpwl.jackpotid
                and
                jpwl.winlineid = #{Value}
        </select>

</mapper>

Here is the mybatis.xml.  We have to disable all caching if we want
our app to work multi-threaded in the settings section.

<configuration>
        <environments default="test">
                <environment id="test">
                        <transactionManager type="JDBC" />
                        <dataSource type="POOLED">
                                <property name="poolMaximumIdleConnections" value="20"></property>
                                <property name="poolMaximumActiveConnections" value="80"></
property>
                                <property name="poolMaximumCheckoutTime" value="600"></property>
                                <property name="poolTimeToWait" value="600"></property>

                                <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
                                <property name="url"
                                        value="jdbc:oracle:thin:@our.secret.co.uk:1521:orcl" />
                                <property name="username" value="SK_TEST" />
                                <property name="password" value="**********" />
                        </dataSource>
                </environment>
        </environments>
        <mappers>
: mappers removed for readibility
                <mapper resource="com/skillkash/ge/mapper/PotMapper.xml" />
                <mapper resource="com/skillkash/ge/mapper/PotTransactionMapper.xml" /
>
                <mapper resource="com/skillkash/ge/mapper/JackpotMapper.xml" />
        </mappers>

Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

nino martinez wael

Extreme wild guess have you troede some of the other connection pools?

On Apr 12, 2011 2:46 PM, "Simon" <[hidden email]> wrote:
> Problem: If we enable caching, our app hangs within 30 seconds. If we
> disable it, it works perfectly.
>
> We are using oracle 11g, and mybatis 3.0.1
>
> We have game engine which manages client games starting and ending
> (think slots game with jackpots).
>
> We have a test harness which calls startGame and endGame in a loop for
> a number of test players, one player per thread.
>
> If we use 1 thread, all is good, we can run say 10,000 games for 1
> player.
>
> If we have mutliple threads, and mybatis caching enabled, then very
> soon (<10 games), the entire engine hangs. We thought it was the DB,
> but our expert Oracle DBA says there are no deadlocks, and all the
> sessions are idle in that they have sent the results back to mybatis
> and are waiting for the next sql command.
>
> Doing a stack dump of the hung engine, I can see that 18 of the 20
> threads are stuck in "Unsafe.park":
>
> Thread [Thread-4] (Suspended)
> Unsafe.park(boolean, long) line: not available [native method]
> LockSupport.park(Object) line: 158
> ReentrantReadWriteLock
> $NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line:
> 747
> ReentrantReadWriteLock
> $NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int) line:
> 877
> ReentrantReadWriteLock
> $NonfairSync(AbstractQueuedSynchronizer).acquireShared(int) line:
> 1197
> ReentrantReadWriteLock$ReadLock.lock() line: 594
> CachingExecutor.query(MappedStatement, Object, RowBounds,
> ResultHandler) line: 52
> DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
> DefaultSqlSession.selectList(String, Object) line: 53
> DefaultSqlSession.selectOne(String, Object) line: 38
> MapperMethod.execute(Object[]) line: 66
> MapperProxy.invoke(Object, Method, Object[]) line: 35
> $Proxy13.selectJackpotBalanceForGame(long) line: not available
> JackpotService.selectJackpotBalanceForGame(long) line: 52
> JackpotService.selectJackpotBalanceForPlayergame(long) line: 302
> EndGame.doAction(APIProperties) line: 73
> ApiServlet.execFunction(APIProperties) line: 148
> DirectApiTester.run(APIProperties) line: 27
> TestMain.runSequence(Tester, int) line: 202
> NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
> Method.invoke(Object, Object...) line: 597
> TestMain$1.run() line: 47
> Thread.run() line: 619
>
> The other two threads were doing this:
>
> Thread [Thread-14] (Suspended)
> SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int)
> line: not available [native method]
> SocketInputStream.read(byte[], int, int) line: 129
> DataPacket(Packet).receive() line: 240
> DataPacket.receive() line: 92
> NetInputStream.getNextPacket() line: 172
> NetInputStream.read(byte[], int, int) line: 117
> NetInputStream.read(byte[]) line: 92
> NetInputStream.read() line: 77
> T4CMAREngine.unmarshalUB1() line: 1034
> T4CMAREngine.unmarshalSB1() line: 1010
> T4C8Oall.receive() line: 588
> T4CPreparedStatement.doOall8(boolean, boolean, boolean, boolean)
> line: 194
> T4CPreparedStatement.executeForDescribe() line: 791
> T4CPreparedStatement.executeMaybeDescribe() line: 866
> T4CPreparedStatement(OracleStatement).doExecuteWithTimeout() line:
> 1186
> T4CPreparedStatement(OraclePreparedStatement).executeInternal() line:
> 3387
> T4CPreparedStatement(OraclePreparedStatement).execute() line: 3488
> OraclePreparedStatementWrapper.execute() line: 1374
> GeneratedMethodAccessor19.invoke(Object, Object[]) line: not
> available
> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
> Method.invoke(Object, Object...) line: 597
> PreparedStatementLogger.invoke(Object, Method, Object[]) line: 45
> $Proxy2.execute() line: not available
> PreparedStatementHandler.query(Statement, ResultHandler) line: 39
> RoutingStatementHandler.query(Statement, ResultHandler) line: 55
> SimpleExecutor.doQuery(MappedStatement, Object, RowBounds,
> ResultHandler) line: 41
> SimpleExecutor(BaseExecutor).query(MappedStatement, Object,
> RowBounds, ResultHandler) line: 94
> CachingExecutor.query(MappedStatement, Object, RowBounds,
> ResultHandler) line: 65
> DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
> DefaultSqlSession.selectList(String, Object) line: 53
> DefaultSqlSession.selectOne(String, Object) line: 38
> MapperMethod.execute(Object[]) line: 66
> MapperProxy.invoke(Object, Method, Object[]) line: 35
> $Proxy13.getLock(long) line: not available
> JackpotService.win(SqlSession, long, long) line: 264
> JackpotWinlineService.settle(SqlSession, Winline, PlayerGame,
> Boolean) line: 112
> WinlineService.settle(SqlSession, Winline, PlayerGame, Boolean) line:
> 170
> WinnableService.settle(SqlSession, Winnable, PlayerGame, Boolean)
> line: 128
> PlayerGameService.endGame(long, Session, PlayerGame, Game, String[])
> line: 307
> MasterGameController.endGame(long, String, long, String[]) line: 47
> EndGame.doAction(APIProperties) line: 59
> ApiServlet.execFunction(APIProperties) line: 148
> DirectApiTester.run(APIProperties) line: 27
> TestMain.runSequence(Tester, int) line: 202
> NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
> Method.invoke(Object, Object...) line: 597
> TestMain$1.run() line: 47
> Thread.run() line: 619
>
> The problem occurs around the only shared resource, the jackpot. We
> get a lock on it if a jackpot is won (1in4 chance for testing), so
> only one person can win it, but dont update the actual jackpot table
> at all during out tests (we insert transactions against the jackpots
> pot account).
>
> Here is the jackpotMapper.xml. Notice all the balance selects have
> useCache="false". the balance functions are just conveinience
> methods, we could have got the balance from the pot for the
> jackpot.poid in the pot mapper (which also have useCache="false").
>
> <?xml version="1.0" encoding="UTF-8" ?>
> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
> "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
> <mapper namespace="com.skillkash.ge.mapper.JackpotMapper">
>
>
> <cache eviction="FIFO" flushInterval="60000" size="512"/>
>
>
> <insert id="insert">
> :removed for brevity.
> </insert>
>
> <select id="select" resultType="com.skillkash.ge.beans.JackpotBean">
> select * from Jackpot
> where id =
> #{value}
> </select>
>
> <resultMap id="selectWithPotsResultMap"
> type="com.skillkash.ge.beans.JackpotBean">
> <association property="pot" column="potid"
> javaType="com.skillkash.ge.beans.Pot"
> select="com.skillkash.ge.mapper.PotMapper.select" />
> <association property="pendingpot" column="pendingpotid"
> javaType="com.skillkash.ge.beans.Pot"
> select="com.skillkash.ge.mapper.PotMapper.select" />
> <association property="seedpot" column="seedpotid"
> javaType="com.skillkash.ge.beans.Pot"
> select="com.skillkash.ge.mapper.PotMapper.select" />
> </resultMap>
>
> <select id="selectWithPots" resultMap="selectWithPotsResultMap">
> select * from Jackpot
> where id = #{value}
> </select>
>
>
> <select id="selectAll" resultMap="selectWithPotsResultMap">
> select * from Jackpot
> </select>
>
> <select id="selectActive" resultMap="selectWithPotsResultMap">
> select unique j.* from
> Jackpot j, game g
> where g.jackpotid = j.id
> and G.DELETEDYN = 0
> </select>
>
> <select id="selectJackpotBalanceForGame" resultType="BigDecimal"
> useCache="false">
> select
> pot.balance
> from pot, game, jackpot
> where
> pot.id =
> jackpot.potid
> and
> game.jackpotid = jackpot.id
> and game.id = #{Value}
> </select>
>
> <select id="selectBalanceForJackpot" resultType="BigDecimal"
> useCache="false">
> select
> pot.balance
> from pot, jackpot
> where
> pot.id = jackpot.potid
> and jackpot.id
> = #{Value}
> </select>
>
> <select id="selectSeedBalanceForJackpot" resultType="BigDecimal"
> useCache="false">
> select
> pot.balance
> from pot, jackpot
> where
> pot.id =
> jackpot.seedpotid
> and
> jackpot.id = #{Value}
> </select>
>
> <select id="getLock" resultType="Long" useCache="false">
> select id
> from jackpot
> where
> id =
> #{Value}
> for update
> </select>
>
> <select id="selectJackpotForWinline"
> resultMap="selectWithPotsResultMap">
> select jp.*
> from
> jackpot jp, jackpotwinline jpwl
> where
> jp.id = jpwl.jackpotid
> and
> jpwl.winlineid = #{Value}
> </select>
>
> </mapper>
>
> Here is the mybatis.xml. We have to disable all caching if we want
> our app to work multi-threaded in the settings section.
>
> <configuration>
> <environments default="test">
> <environment id="test">
> <transactionManager type="JDBC" />
> <dataSource type="POOLED">
> <property name="poolMaximumIdleConnections" value="20"></property>
> <property name="poolMaximumActiveConnections" value="80"></
> property>
> <property name="poolMaximumCheckoutTime" value="600"></property>
> <property name="poolTimeToWait" value="600"></property>
>
> <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
> <property name="url"
> value="jdbc:oracle:thin:@our.secret.co.uk:1521:orcl" />
> <property name="username" value="SK_TEST" />
> <property name="password" value="**********" />
> </dataSource>
> </environment>
> </environments>
> <mappers>
> : mappers removed for readibility
> <mapper resource="com/skillkash/ge/mapper/PotMapper.xml" />
> <mapper resource="com/skillkash/ge/mapper/PotTransactionMapper.xml" /
>>
> <mapper resource="com/skillkash/ge/mapper/JackpotMapper.xml" />
> </mappers>
>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

nino martinez wael
troede =tried

2011/4/14 nino martinez wael <[hidden email]>:

> Extreme wild guess have you troede some of the other connection pools?
>
> On Apr 12, 2011 2:46 PM, "Simon" <[hidden email]> wrote:
>> Problem: If we enable caching, our app hangs within 30 seconds. If we
>> disable it, it works perfectly.
>>
>> We are using oracle 11g, and mybatis 3.0.1
>>
>> We have game engine which manages client games starting and ending
>> (think slots game with jackpots).
>>
>> We have a test harness which calls startGame and endGame in a loop for
>> a number of test players, one player per thread.
>>
>> If we use 1 thread, all is good, we can run say 10,000 games for 1
>> player.
>>
>> If we have mutliple threads, and mybatis caching enabled, then very
>> soon (<10 games), the entire engine hangs. We thought it was the DB,
>> but our expert Oracle DBA says there are no deadlocks, and all the
>> sessions are idle in that they have sent the results back to mybatis
>> and are waiting for the next sql command.
>>
>> Doing a stack dump of the hung engine, I can see that 18 of the 20
>> threads are stuck in "Unsafe.park":
>>
>> Thread [Thread-4] (Suspended)
>> Unsafe.park(boolean, long) line: not available [native method]
>> LockSupport.park(Object) line: 158
>> ReentrantReadWriteLock
>> $NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line:
>> 747
>> ReentrantReadWriteLock
>> $NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int) line:
>> 877
>> ReentrantReadWriteLock
>> $NonfairSync(AbstractQueuedSynchronizer).acquireShared(int) line:
>> 1197
>> ReentrantReadWriteLock$ReadLock.lock() line: 594
>> CachingExecutor.query(MappedStatement, Object, RowBounds,
>> ResultHandler) line: 52
>> DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>> DefaultSqlSession.selectList(String, Object) line: 53
>> DefaultSqlSession.selectOne(String, Object) line: 38
>> MapperMethod.execute(Object[]) line: 66
>> MapperProxy.invoke(Object, Method, Object[]) line: 35
>> $Proxy13.selectJackpotBalanceForGame(long) line: not available
>> JackpotService.selectJackpotBalanceForGame(long) line: 52
>> JackpotService.selectJackpotBalanceForPlayergame(long) line: 302
>> EndGame.doAction(APIProperties) line: 73
>> ApiServlet.execFunction(APIProperties) line: 148
>> DirectApiTester.run(APIProperties) line: 27
>> TestMain.runSequence(Tester, int) line: 202
>> NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
>> available [native method]
>> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>> Method.invoke(Object, Object...) line: 597
>> TestMain$1.run() line: 47
>> Thread.run() line: 619
>>
>> The other two threads were doing this:
>>
>> Thread [Thread-14] (Suspended)
>> SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int)
>> line: not available [native method]
>> SocketInputStream.read(byte[], int, int) line: 129
>> DataPacket(Packet).receive() line: 240
>> DataPacket.receive() line: 92
>> NetInputStream.getNextPacket() line: 172
>> NetInputStream.read(byte[], int, int) line: 117
>> NetInputStream.read(byte[]) line: 92
>> NetInputStream.read() line: 77
>> T4CMAREngine.unmarshalUB1() line: 1034
>> T4CMAREngine.unmarshalSB1() line: 1010
>> T4C8Oall.receive() line: 588
>> T4CPreparedStatement.doOall8(boolean, boolean, boolean, boolean)
>> line: 194
>> T4CPreparedStatement.executeForDescribe() line: 791
>> T4CPreparedStatement.executeMaybeDescribe() line: 866
>> T4CPreparedStatement(OracleStatement).doExecuteWithTimeout() line:
>> 1186
>> T4CPreparedStatement(OraclePreparedStatement).executeInternal() line:
>> 3387
>> T4CPreparedStatement(OraclePreparedStatement).execute() line: 3488
>> OraclePreparedStatementWrapper.execute() line: 1374
>> GeneratedMethodAccessor19.invoke(Object, Object[]) line: not
>> available
>> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>> Method.invoke(Object, Object...) line: 597
>> PreparedStatementLogger.invoke(Object, Method, Object[]) line: 45
>> $Proxy2.execute() line: not available
>> PreparedStatementHandler.query(Statement, ResultHandler) line: 39
>> RoutingStatementHandler.query(Statement, ResultHandler) line: 55
>> SimpleExecutor.doQuery(MappedStatement, Object, RowBounds,
>> ResultHandler) line: 41
>> SimpleExecutor(BaseExecutor).query(MappedStatement, Object,
>> RowBounds, ResultHandler) line: 94
>> CachingExecutor.query(MappedStatement, Object, RowBounds,
>> ResultHandler) line: 65
>> DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>> DefaultSqlSession.selectList(String, Object) line: 53
>> DefaultSqlSession.selectOne(String, Object) line: 38
>> MapperMethod.execute(Object[]) line: 66
>> MapperProxy.invoke(Object, Method, Object[]) line: 35
>> $Proxy13.getLock(long) line: not available
>> JackpotService.win(SqlSession, long, long) line: 264
>> JackpotWinlineService.settle(SqlSession, Winline, PlayerGame,
>> Boolean) line: 112
>> WinlineService.settle(SqlSession, Winline, PlayerGame, Boolean) line:
>> 170
>> WinnableService.settle(SqlSession, Winnable, PlayerGame, Boolean)
>> line: 128
>> PlayerGameService.endGame(long, Session, PlayerGame, Game, String[])
>> line: 307
>> MasterGameController.endGame(long, String, long, String[]) line: 47
>> EndGame.doAction(APIProperties) line: 59
>> ApiServlet.execFunction(APIProperties) line: 148
>> DirectApiTester.run(APIProperties) line: 27
>> TestMain.runSequence(Tester, int) line: 202
>> NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
>> available [native method]
>> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>> Method.invoke(Object, Object...) line: 597
>> TestMain$1.run() line: 47
>> Thread.run() line: 619
>>
>> The problem occurs around the only shared resource, the jackpot. We
>> get a lock on it if a jackpot is won (1in4 chance for testing), so
>> only one person can win it, but dont update the actual jackpot table
>> at all during out tests (we insert transactions against the jackpots
>> pot account).
>>
>> Here is the jackpotMapper.xml. Notice all the balance selects have
>> useCache="false". the balance functions are just conveinience
>> methods, we could have got the balance from the pot for the
>> jackpot.poid in the pot mapper (which also have useCache="false").
>>
>> <?xml version="1.0" encoding="UTF-8" ?>
>> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
>> "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
>> <mapper namespace="com.skillkash.ge.mapper.JackpotMapper">
>>
>>
>> <cache eviction="FIFO" flushInterval="60000" size="512"/>
>>
>>
>> <insert id="insert">
>> :removed for brevity.
>> </insert>
>>
>> <select id="select" resultType="com.skillkash.ge.beans.JackpotBean">
>> select * from Jackpot
>> where id =
>> #{value}
>> </select>
>>
>> <resultMap id="selectWithPotsResultMap"
>> type="com.skillkash.ge.beans.JackpotBean">
>> <association property="pot" column="potid"
>> javaType="com.skillkash.ge.beans.Pot"
>> select="com.skillkash.ge.mapper.PotMapper.select" />
>> <association property="pendingpot" column="pendingpotid"
>> javaType="com.skillkash.ge.beans.Pot"
>> select="com.skillkash.ge.mapper.PotMapper.select" />
>> <association property="seedpot" column="seedpotid"
>> javaType="com.skillkash.ge.beans.Pot"
>> select="com.skillkash.ge.mapper.PotMapper.select" />
>> </resultMap>
>>
>> <select id="selectWithPots" resultMap="selectWithPotsResultMap">
>> select * from Jackpot
>> where id = #{value}
>> </select>
>>
>>
>> <select id="selectAll" resultMap="selectWithPotsResultMap">
>> select * from Jackpot
>> </select>
>>
>> <select id="selectActive" resultMap="selectWithPotsResultMap">
>> select unique j.* from
>> Jackpot j, game g
>> where g.jackpotid = j.id
>> and G.DELETEDYN = 0
>> </select>
>>
>> <select id="selectJackpotBalanceForGame" resultType="BigDecimal"
>> useCache="false">
>> select
>> pot.balance
>> from pot, game, jackpot
>> where
>> pot.id =
>> jackpot.potid
>> and
>> game.jackpotid = jackpot.id
>> and game.id = #{Value}
>> </select>
>>
>> <select id="selectBalanceForJackpot" resultType="BigDecimal"
>> useCache="false">
>> select
>> pot.balance
>> from pot, jackpot
>> where
>> pot.id = jackpot.potid
>> and jackpot.id
>> = #{Value}
>> </select>
>>
>> <select id="selectSeedBalanceForJackpot" resultType="BigDecimal"
>> useCache="false">
>> select
>> pot.balance
>> from pot, jackpot
>> where
>> pot.id =
>> jackpot.seedpotid
>> and
>> jackpot.id = #{Value}
>> </select>
>>
>> <select id="getLock" resultType="Long" useCache="false">
>> select id
>> from jackpot
>> where
>> id =
>> #{Value}
>> for update
>> </select>
>>
>> <select id="selectJackpotForWinline"
>> resultMap="selectWithPotsResultMap">
>> select jp.*
>> from
>> jackpot jp, jackpotwinline jpwl
>> where
>> jp.id = jpwl.jackpotid
>> and
>> jpwl.winlineid = #{Value}
>> </select>
>>
>> </mapper>
>>
>> Here is the mybatis.xml. We have to disable all caching if we want
>> our app to work multi-threaded in the settings section.
>>
>> <configuration>
>> <environments default="test">
>> <environment id="test">
>> <transactionManager type="JDBC" />
>> <dataSource type="POOLED">
>> <property name="poolMaximumIdleConnections" value="20"></property>
>> <property name="poolMaximumActiveConnections" value="80"></
>> property>
>> <property name="poolMaximumCheckoutTime" value="600"></property>
>> <property name="poolTimeToWait" value="600"></property>
>>
>> <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
>> <property name="url"
>> value="jdbc:oracle:thin:@our.secret.co.uk:1521:orcl" />
>> <property name="username" value="SK_TEST" />
>> <property name="password" value="**********" />
>> </dataSource>
>> </environment>
>> </environments>
>> <mappers>
>> : mappers removed for readibility
>> <mapper resource="com/skillkash/ge/mapper/PotMapper.xml" />
>> <mapper resource="com/skillkash/ge/mapper/PotTransactionMapper.xml" /
>>>
>> <mapper resource="com/skillkash/ge/mapper/JackpotMapper.xml" />
>> </mappers>
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Simon
In reply to this post by nino martinez wael
> Extreme wild guess have you tried some of the other connection pools?

Er, for example?  We certainly want to avoid spring and all that
baggage/complication/.

Do you think the standard connection pool used by mybatis has bugs
which mean the caching is unusable?

Does anyone else use the standard mybatis pooing and caching?



Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

nino martinez wael
2011/4/15 Simon <[hidden email]>:
>> Extreme wild guess have you tried some of the other connection pools?
>
> Er, for example?  We certainly want to avoid spring and all that
> baggage/complication/.
Im not sure how spring are these days, but I find that guice
simplifies my code alot, and the mybatis guice integration blends in
perfectly.
>
> Do you think the standard connection pool used by mybatis has bugs
> which mean the caching is unusable?
No i don't think so, but one never knows, hence the wild guess :) you
could try switching to bonecp?
>
> Does anyone else use the standard mybatis pooing and caching?
Im not sure what the standard pool provider are, c3p0?..
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Simon
In reply to this post by Simon
Bump.

Does anyone out there use the default mybatis cache and it works?

We cannot get past this Unsafe.park lockup in the ibatis caching code,
and are wondering how anyone gets the same issue if they have
multithreaded select for updates (and there would be no point in
having a select for update if it could not be called from multiple
threads...) Switching the cache off for the offending statements does
not work - you have to switch off the the cache for the entire mapper
to stop it caching the select for update statement (i.e.
using ...useCache="false"> does not seem to work - it tries to cache
it anyway and hangs the app.

thanks in advance for any feedback.

On Apr 12, 2:46 pm, Simon <[hidden email]> wrote:

> Problem: If we enable caching, our app hangs within 30 seconds.  If we
> disable it, it works perfectly.
>
> We are using oracle 11g, and mybatis 3.0.1
>
> We have game engine which manages client games starting and ending
> (think slots game with jackpots).
>
> We have a test harness which calls startGame and endGame in a loop for
> a number of test players, one player per thread.
>
> If we use 1 thread, all is good, we can run say 10,000 games for 1
> player.
>
> If we have mutliple threads, and mybatis caching enabled, then very
> soon (<10 games), the entire engine hangs.  We thought it was the DB,
> but our expert Oracle DBA says there are no deadlocks, and all the
> sessions are idle in that they have sent the results back to mybatis
> and are waiting for the next sql command.
>
> Doing a stack dump of the hung engine, I can see that 18 of the 20
> threads are stuck in "Unsafe.park":
>
> Thread [Thread-4] (Suspended)
>         Unsafe.park(boolean, long) line: not available [native method]
>         LockSupport.park(Object) line: 158
>         ReentrantReadWriteLock
> $NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line:
> 747
>         ReentrantReadWriteLock
> $NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int) line:
> 877
>         ReentrantReadWriteLock
> $NonfairSync(AbstractQueuedSynchronizer).acquireShared(int) line:
> 1197
>         ReentrantReadWriteLock$ReadLock.lock() line: 594
>         CachingExecutor.query(MappedStatement, Object, RowBounds,
> ResultHandler) line: 52
>         DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>         DefaultSqlSession.selectList(String, Object) line: 53
>         DefaultSqlSession.selectOne(String, Object) line: 38
>         MapperMethod.execute(Object[]) line: 66
>         MapperProxy.invoke(Object, Method, Object[]) line: 35
>         $Proxy13.selectJackpotBalanceForGame(long) line: not available
>         JackpotService.selectJackpotBalanceForGame(long) line: 52
>         JackpotService.selectJackpotBalanceForPlayergame(long) line: 302
>         EndGame.doAction(APIProperties) line: 73
>         ApiServlet.execFunction(APIProperties) line: 148
>         DirectApiTester.run(APIProperties) line: 27
>         TestMain.runSequence(Tester, int) line: 202
>         NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>         NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>         DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>         Method.invoke(Object, Object...) line: 597
>         TestMain$1.run() line: 47
>         Thread.run() line: 619
>
> The other two threads were doing this:
>
> Thread [Thread-14] (Suspended)
>         SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int)
> line: not available [native method]
>         SocketInputStream.read(byte[], int, int) line: 129
>         DataPacket(Packet).receive() line: 240
>         DataPacket.receive() line: 92
>         NetInputStream.getNextPacket() line: 172
>         NetInputStream.read(byte[], int, int) line: 117
>         NetInputStream.read(byte[]) line: 92
>         NetInputStream.read() line: 77
>         T4CMAREngine.unmarshalUB1() line: 1034
>         T4CMAREngine.unmarshalSB1() line: 1010
>         T4C8Oall.receive() line: 588
>         T4CPreparedStatement.doOall8(boolean, boolean, boolean, boolean)
> line: 194
>         T4CPreparedStatement.executeForDescribe() line: 791
>         T4CPreparedStatement.executeMaybeDescribe() line: 866
>         T4CPreparedStatement(OracleStatement).doExecuteWithTimeout() line:
> 1186
>         T4CPreparedStatement(OraclePreparedStatement).executeInternal() line:
> 3387
>         T4CPreparedStatement(OraclePreparedStatement).execute() line: 3488
>         OraclePreparedStatementWrapper.execute() line: 1374
>         GeneratedMethodAccessor19.invoke(Object, Object[]) line: not
> available
>         DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>         Method.invoke(Object, Object...) line: 597
>         PreparedStatementLogger.invoke(Object, Method, Object[]) line: 45
>         $Proxy2.execute() line: not available
>         PreparedStatementHandler.query(Statement, ResultHandler) line: 39
>         RoutingStatementHandler.query(Statement, ResultHandler) line: 55
>         SimpleExecutor.doQuery(MappedStatement, Object, RowBounds,
> ResultHandler) line: 41
>         SimpleExecutor(BaseExecutor).query(MappedStatement, Object,
> RowBounds, ResultHandler) line: 94
>         CachingExecutor.query(MappedStatement, Object, RowBounds,
> ResultHandler) line: 65
>         DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>         DefaultSqlSession.selectList(String, Object) line: 53
>         DefaultSqlSession.selectOne(String, Object) line: 38
>         MapperMethod.execute(Object[]) line: 66
>         MapperProxy.invoke(Object, Method, Object[]) line: 35
>         $Proxy13.getLock(long) line: not available
>         JackpotService.win(SqlSession, long, long) line: 264
>         JackpotWinlineService.settle(SqlSession, Winline, PlayerGame,
> Boolean) line: 112
>         WinlineService.settle(SqlSession, Winline, PlayerGame, Boolean) line:
> 170
>         WinnableService.settle(SqlSession, Winnable, PlayerGame, Boolean)
> line: 128
>         PlayerGameService.endGame(long, Session, PlayerGame, Game, String[])
> line: 307
>         MasterGameController.endGame(long, String, long, String[]) line: 47
>         EndGame.doAction(APIProperties) line: 59
>         ApiServlet.execFunction(APIProperties) line: 148
>         DirectApiTester.run(APIProperties) line: 27
>         TestMain.runSequence(Tester, int) line: 202
>         NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>         NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>         DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>         Method.invoke(Object, Object...) line: 597
>         TestMain$1.run() line: 47
>         Thread.run() line: 619
>
> The problem occurs around the only shared resource, the jackpot.  We
> get a lock on it if a jackpot is won (1in4 chance for testing), so
> only one person can win it, but dont update the actual jackpot table
> at all during out tests (we insert transactions against the jackpots
> pot account).
>
> Here is the jackpotMapper.xml. Notice all the balance selects have
> useCache="false".  the balance functions are just conveinience
> methods, we could have got the balance from the pot for the
> jackpot.poid in the pot mapper (which also have useCache="false").
>
> <?xml version="1.0" encoding="UTF-8" ?>
> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
>                 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
> <mapper namespace="com.skillkash.ge.mapper.JackpotMapper">
>
>         <cache eviction="FIFO" flushInterval="60000" size="512"/>
>
>         <insert id="insert">
> :removed for brevity.
>         </insert>
>
>         <select id="select" resultType="com.skillkash.ge.beans.JackpotBean">
>                 select * from Jackpot
>                 where id =
>                 #{value}
>         </select>
>
>         <resultMap id="selectWithPotsResultMap"
> type="com.skillkash.ge.beans.JackpotBean">
>                 <association property="pot" column="potid"
>                         javaType="com.skillkash.ge.beans.Pot"
> select="com.skillkash.ge.mapper.PotMapper.select" />
>                 <association property="pendingpot" column="pendingpotid"
>                         javaType="com.skillkash.ge.beans.Pot"
> select="com.skillkash.ge.mapper.PotMapper.select" />
>                 <association property="seedpot" column="seedpotid"
>                         javaType="com.skillkash.ge.beans.Pot"
> select="com.skillkash.ge.mapper.PotMapper.select" />
>         </resultMap>
>
>         <select id="selectWithPots" resultMap="selectWithPotsResultMap">
>                 select * from Jackpot
>                 where id = #{value}
>         </select>
>
>         <select id="selectAll" resultMap="selectWithPotsResultMap">
>                 select * from Jackpot
>         </select>
>
>         <select id="selectActive" resultMap="selectWithPotsResultMap">
>                 select unique j.* from
>                 Jackpot j, game g
>                 where g.jackpotid = j.id
>                 and G.DELETEDYN = 0
>         </select>
>
>         <select id="selectJackpotBalanceForGame" resultType="BigDecimal"
>                 useCache="false">
>                 select
>                 pot.balance
>                 from pot, game, jackpot
>                 where
>                 pot.id =
>                 jackpot.potid
>                 and
>                 game.jackpotid = jackpot.id
>                 and game.id = #{Value}
>         </select>
>
>         <select id="selectBalanceForJackpot" resultType="BigDecimal"
>                 useCache="false">
>                 select
>                 pot.balance
>                 from pot, jackpot
>                 where
>                 pot.id = jackpot.potid
>                 and jackpot.id
>                 = #{Value}
>         </select>
>
>         <select id="selectSeedBalanceForJackpot" resultType="BigDecimal"
>                 useCache="false">
>                 select
>                 pot.balance
>                 from pot, jackpot
>                 where
>                 pot.id =
>                 jackpot.seedpotid
>                 and
>                 jackpot.id = #{Value}
>         </select>
>
>         <select id="getLock" resultType="Long" useCache="false">
>                 select id
>                 from jackpot
>                 where
>                 id =
>                 #{Value}
>                 for update
>         </select>
>
>         <select id="selectJackpotForWinline"
> resultMap="selectWithPotsResultMap">
>                 select jp.*
>                 from
>                 jackpot jp, jackpotwinline jpwl
>                 where
>                 jp.id = jpwl.jackpotid
>                 and
>                 jpwl.winlineid = #{Value}
>         </select>
>
> </mapper>
>
> Here is the mybatis.xml.  We have to disable all caching if we want
> our app to work multi-threaded in the settings section.
>
> <configuration>
>         <environments default="test">
>                 <environment id="test">
>                         <transactionManager type="JDBC" />
>                         <dataSource type="POOLED">
>                                 <property name="poolMaximumIdleConnections" value="20"></property>
>                                 <property name="poolMaximumActiveConnections" value="80"></
> property>
>                                 <property name="poolMaximumCheckoutTime" value="600"></property>
>                                 <property name="poolTimeToWait" value="600"></property>
>
>                                 <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
>                                 <property name="url"
>                                         value="jdbc:oracle:thin:@our.secret.co.uk:1521:orcl" />
>                                 <property name="username" value="SK_TEST" />
>                                 <property name="password" value="**********" />
>                         </dataSource>
>                 </environment>
>         </environments>
>         <mappers>
> : mappers removed for readibility
>                 <mapper resource="com/skillkash/ge/mapper/PotMapper.xml" />
>                 <mapper resource="com/skillkash/ge/mapper/PotTransactionMapper.xml" /
>
>                 <mapper resource="com/skillkash/ge/mapper/JackpotMapper.xml" />
>         </mappers>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Simon
Bump?

We have switched to using ehcache, but get the same problem - if we run our app concurrently, after a very short time (e.g. 1 minute) all threads hang in Unsafe.park(). which is in the bowels of the mybatis caching code - and must be a bug.   Recently, we came across a large company who is also using mybatis, and is having exactly the same problem.  They could not find a solution, and are switching to a different mapping product.

Has anyone used any form of caching successfully with mybatis (without spring etc)?

Below are a couple of example threads. Some are doing inserts, some are doing selects.


Thread [Thread-1]
    Unsafe.park(boolean, long) line: not available [native method]   
    LockSupport.park(Object) line: 158   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line: 747   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireQueued(AbstractQueuedSynchronizer$Node, int) line: 778   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquire(int) line: 1114   
    ReentrantReadWriteLock$WriteLock.lock() line: 807   
    TransactionalCache.commit() line: 56   
    TransactionalCacheManager.commit() line: 22   
    CachingExecutor.close(boolean) line: 30   
    DefaultSqlSession.close() line: 146   
    PlayerGameService.endGame(long, Session, PlayerGame, Game, String[], long, boolean) line: 466   
    MasterGameController.endGame(long, String, long, String[], long, boolean) line: 48   
    EndGame.doAction(APIProperties) line: 65   
    ApiServlet.execFunction(APIProperties) line: 139   
    DirectApiTester.run(APIProperties) line: 25   
    TestMain.runSequence(Tester, int) line: 209   
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]   
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39   
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25   
    Method.invoke(Object, Object...) line: 597   
    TestMain$1.run() line: 49   
    Thread.run() line: 619   


Thread [Thread-2]
    Unsafe.park(boolean, long) line: not available [native method]   
    LockSupport.park(Object) line: 158   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line: 747   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int) line: 877   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int) line: 1197   
    ReentrantReadWriteLock$ReadLock.lock() line: 594   
    CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler) line: 52   
    DefaultSqlSession.selectList(String, Object, RowBounds) line: 59   
    DefaultSqlSession.selectList(String, Object) line: 53   
    DefaultSqlSession.selectOne(String, Object) line: 38   
    MapperMethod.execute(Object[]) line: 66   
    MapperProxy.invoke(Object, Method, Object[]) line: 35   
    $Proxy7.selectSeedBalanceForJackpot(long) line: not available   
    JackpotService.win(SqlSession, long, long) line: 280   
    WinlineService.settle(SqlSession, JackpotWinline, PlayerGame, boolean) line: 787   
    WinlineService.settle(SqlSession, Winline, PlayerGame, boolean, boolean) line: 335   
    WinnableService.settle(SqlSession, Winnable, PlayerGame, boolean, boolean) line: 128   
    PlayerGameService.endGame(long, Session, PlayerGame, Game, String[], long, boolean) line: 411   
    MasterGameController.endGame(long, String, long, String[], long, boolean) line: 48   
    EndGame.doAction(APIProperties) line: 65   
    ApiServlet.execFunction(APIProperties) line: 139   
    DirectApiTester.run(APIProperties) line: 25   
    TestMain.runSequence(Tester, int) line: 209   
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]   
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39   
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25   
    Method.invoke(Object, Object...) line: 597   
    TestMain$1.run() line: 49   
    Thread.run() line: 619   


Thread [Thread-5]
    Unsafe.park(boolean, long) line: not available [native method]   
    LockSupport.park(Object) line: 158   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line: 747   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int) line: 877   
    ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int) line: 1197   
    ReentrantReadWriteLock$ReadLock.lock() line: 594   
    CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler) line: 52   
    DefaultSqlSession.selectList(String, Object, RowBounds) line: 59   
    DefaultSqlSession.selectList(String, Object) line: 53   
    DefaultSqlSession.selectOne(String, Object) line: 38   
    MapperMethod.execute(Object[]) line: 66   
    MapperProxy.invoke(Object, Method, Object[]) line: 35   
    $Proxy7.selectJackpotBalanceForGame(long) line: not available   
    JackpotService.selectJackpotBalanceForGame(long) line: 53   
    JackpotService.selectJackpotBalanceForPlayergame(long) line: 314   
    EndGame.doAction(APIProperties) line: 79   
    ApiServlet.execFunction(APIProperties) line: 139   
    DirectApiTester.run(APIProperties) line: 25   
    TestMain.runSequence(Tester, int) line: 209   
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]   
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39   
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25   
    Method.invoke(Object, Object...) line: 597   
    TestMain$1.run() line: 49   
    Thread.run() line: 619   



Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Larry Meadors
I'm using the built-in postgresql pool with the default cache without problems.

Are you sharing your sql sessions or something?

Larry


On Mon, Jun 27, 2011 at 6:41 AM, Simon <[hidden email]> wrote:

> Bump?
>
> We have switched to using ehcache, but get the same problem - if we run our
> app concurrently, after a very short time (e.g. 1 minute) all threads hang
> in Unsafe.park(). which is in the bowels of the mybatis caching code - and
> must be a bug.   Recently, we came across a large company who is also using
> mybatis, and is having exactly the same problem.  They could not find a
> solution, and are switching to a different mapping product.
>
> Has anyone used any form of caching successfully with mybatis (without
> spring etc)?
>
> Below are a couple of example threads. Some are doing inserts, some are
> doing selects.
>
>
> Thread [Thread-1]
>     Unsafe.park(boolean, long) line: not available [native method]
>     LockSupport.park(Object) line: 158
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
> line: 747
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireQueued(AbstractQueuedSynchronizer$Node,
> int) line: 778
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquire(int)
> line: 1114
>     ReentrantReadWriteLock$WriteLock.lock() line: 807
>     TransactionalCache.commit() line: 56
>     TransactionalCacheManager.commit() line: 22
>     CachingExecutor.close(boolean) line: 30
>     DefaultSqlSession.close() line: 146
>     PlayerGameService.endGame(long, Session, PlayerGame, Game, String[],
> long, boolean) line: 466
>     MasterGameController.endGame(long, String, long, String[], long,
> boolean) line: 48
>     EndGame.doAction(APIProperties) line: 65
>     ApiServlet.execFunction(APIProperties) line: 139
>     DirectApiTester.run(APIProperties) line: 25
>     TestMain.runSequence(Tester, int) line: 209
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>     Method.invoke(Object, Object...) line: 597
>     TestMain$1.run() line: 49
>     Thread.run() line: 619
>
>
> Thread [Thread-2]
>     Unsafe.park(boolean, long) line: not available [native method]
>     LockSupport.park(Object) line: 158
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
> line: 747
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int)
> line: 877
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int)
> line: 1197
>     ReentrantReadWriteLock$ReadLock.lock() line: 594
>     CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler)
> line: 52
>     DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>     DefaultSqlSession.selectList(String, Object) line: 53
>     DefaultSqlSession.selectOne(String, Object) line: 38
>     MapperMethod.execute(Object[]) line: 66
>     MapperProxy.invoke(Object, Method, Object[]) line: 35
>     $Proxy7.selectSeedBalanceForJackpot(long) line: not available
>     JackpotService.win(SqlSession, long, long) line: 280
>     WinlineService.settle(SqlSession, JackpotWinline, PlayerGame, boolean)
> line: 787
>     WinlineService.settle(SqlSession, Winline, PlayerGame, boolean, boolean)
> line: 335
>     WinnableService.settle(SqlSession, Winnable, PlayerGame, boolean,
> boolean) line: 128
>     PlayerGameService.endGame(long, Session, PlayerGame, Game, String[],
> long, boolean) line: 411
>     MasterGameController.endGame(long, String, long, String[], long,
> boolean) line: 48
>     EndGame.doAction(APIProperties) line: 65
>     ApiServlet.execFunction(APIProperties) line: 139
>     DirectApiTester.run(APIProperties) line: 25
>     TestMain.runSequence(Tester, int) line: 209
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>     Method.invoke(Object, Object...) line: 597
>     TestMain$1.run() line: 49
>     Thread.run() line: 619
>
>
> Thread [Thread-5]
>     Unsafe.park(boolean, long) line: not available [native method]
>     LockSupport.park(Object) line: 158
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
> line: 747
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int)
> line: 877
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int)
> line: 1197
>     ReentrantReadWriteLock$ReadLock.lock() line: 594
>     CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler)
> line: 52
>     DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>     DefaultSqlSession.selectList(String, Object) line: 53
>     DefaultSqlSession.selectOne(String, Object) line: 38
>     MapperMethod.execute(Object[]) line: 66
>     MapperProxy.invoke(Object, Method, Object[]) line: 35
>     $Proxy7.selectJackpotBalanceForGame(long) line: not available
>     JackpotService.selectJackpotBalanceForGame(long) line: 53
>     JackpotService.selectJackpotBalanceForPlayergame(long) line: 314
>     EndGame.doAction(APIProperties) line: 79
>     ApiServlet.execFunction(APIProperties) line: 139
>     DirectApiTester.run(APIProperties) line: 25
>     TestMain.runSequence(Tester, int) line: 209
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>     Method.invoke(Object, Object...) line: 597
>     TestMain$1.run() line: 49
>     Thread.run() line: 619
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Jeff Butler
In reply to this post by Simon
The best thing you can do is this...

Write a unit test that demonstrates this behavior in the style of the
existing MyBatis unit tests (HSQLDB, no Spring, no Guice, etc. )

Once you have this, then file a bug report with the unit test attached.

Jeff Butler


On 6/27/11, Simon <[hidden email]> wrote:

> Bump?
>
> We have switched to using ehcache, but get the same problem - if we run our
> app concurrently, after a very short time (e.g. 1 minute) all threads hang
> in Unsafe.park(). which is in the bowels of the mybatis caching code - and
> must be a bug.   Recently, we came across a large company who is also using
> mybatis, and is having exactly the same problem.  They could not find a
> solution, and are switching to a different mapping product.
>
> Has anyone used any form of caching successfully with mybatis (without
> spring etc)?
>
> Below are a couple of example threads. Some are doing inserts, some are
> doing selects.
>
>
> Thread [Thread-1]
>     Unsafe.park(boolean, long) line: not available [native method]
>     LockSupport.park(Object) line: 158
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
> line: 747
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireQueued(AbstractQueuedSynchronizer$Node,
> int) line: 778
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquire(int)
> line: 1114
>     ReentrantReadWriteLock$WriteLock.lock() line: 807
>     TransactionalCache.commit() line: 56
>     TransactionalCacheManager.commit() line: 22
>     CachingExecutor.close(boolean) line: 30
>     DefaultSqlSession.close() line: 146
>     PlayerGameService.endGame(long, Session, PlayerGame, Game, String[],
> long, boolean) line: 466
>     MasterGameController.endGame(long, String, long, String[], long,
> boolean) line: 48
>     EndGame.doAction(APIProperties) line: 65
>     ApiServlet.execFunction(APIProperties) line: 139
>     DirectApiTester.run(APIProperties) line: 25
>     TestMain.runSequence(Tester, int) line: 209
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>     Method.invoke(Object, Object...) line: 597
>     TestMain$1.run() line: 49
>     Thread.run() line: 619
>
>
> Thread [Thread-2]
>     Unsafe.park(boolean, long) line: not available [native method]
>     LockSupport.park(Object) line: 158
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
> line: 747
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int)
> line: 877
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int)
> line: 1197
>     ReentrantReadWriteLock$ReadLock.lock() line: 594
>     CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler)
> line: 52
>     DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>     DefaultSqlSession.selectList(String, Object) line: 53
>     DefaultSqlSession.selectOne(String, Object) line: 38
>     MapperMethod.execute(Object[]) line: 66
>     MapperProxy.invoke(Object, Method, Object[]) line: 35
>     $Proxy7.selectSeedBalanceForJackpot(long) line: not available
>     JackpotService.win(SqlSession, long, long) line: 280
>     WinlineService.settle(SqlSession, JackpotWinline, PlayerGame, boolean)
> line: 787
>     WinlineService.settle(SqlSession, Winline, PlayerGame, boolean, boolean)
> line: 335
>     WinnableService.settle(SqlSession, Winnable, PlayerGame, boolean,
> boolean) line: 128
>     PlayerGameService.endGame(long, Session, PlayerGame, Game, String[],
> long, boolean) line: 411
>     MasterGameController.endGame(long, String, long, String[], long,
> boolean) line: 48
>     EndGame.doAction(APIProperties) line: 65
>     ApiServlet.execFunction(APIProperties) line: 139
>     DirectApiTester.run(APIProperties) line: 25
>     TestMain.runSequence(Tester, int) line: 209
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>     Method.invoke(Object, Object...) line: 597
>     TestMain$1.run() line: 49
>     Thread.run() line: 619
>
>
> Thread [Thread-5]
>     Unsafe.park(boolean, long) line: not available [native method]
>     LockSupport.park(Object) line: 158
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
> line: 747
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireShared(int)
> line: 877
>
> ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer).acquireShared(int)
> line: 1197
>     ReentrantReadWriteLock$ReadLock.lock() line: 594
>     CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler)
> line: 52
>     DefaultSqlSession.selectList(String, Object, RowBounds) line: 59
>     DefaultSqlSession.selectList(String, Object) line: 53
>     DefaultSqlSession.selectOne(String, Object) line: 38
>     MapperMethod.execute(Object[]) line: 66
>     MapperProxy.invoke(Object, Method, Object[]) line: 35
>     $Proxy7.selectJackpotBalanceForGame(long) line: not available
>     JackpotService.selectJackpotBalanceForGame(long) line: 53
>     JackpotService.selectJackpotBalanceForPlayergame(long) line: 314
>     EndGame.doAction(APIProperties) line: 79
>     ApiServlet.execFunction(APIProperties) line: 139
>     DirectApiTester.run(APIProperties) line: 25
>     TestMain.runSequence(Tester, int) line: 209
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
>     Method.invoke(Object, Object...) line: 597
>     TestMain$1.run() line: 49
>     Thread.run() line: 619
>
>
>
>

--
Sent from my mobile device
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Simon
In reply to this post by Larry Meadors
We are using the plain mybatis Resources, mybatis.xml and mybatis
SqlSessionFactory etc.  The sql sessions are not shared with any other
app.  When we run our tests, only our app is running against the DB.
If we enable caching in our jackpot mapper, which has a select for
update in it, it always hangs in the mybatis caching code.  However,
if we enable only caching in other totaly harmless static classes also
it sometimes hangs all threads in the same method: unsafe.park().  If
we disable caching in every mapper, the app works perfectly with
thousands of concurrent tests.  We only chache some selects based on
time, where it doesnt matter if the data is slightly old (i.e. not
balances or similar).

Simon.

On Jun 27, 2:50 pm, Larry Meadors <[hidden email]> wrote:
> I'm using the built-in postgresql pool with the default cache without problems.
>
> Are you sharing your sql sessions or something?
>
> Larry
>
> On Mon, Jun 27, 2011 at 6:41 AM, Simon <[hidden email]> wrote:
> > Bump?
>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Richard Yee
What do your "harmless static classes" look like? Sending the code and configuration would make solving the problem easier.

Richard

Sent from my iPhone

On Jun 28, 2011, at 5:38 AM, Simon <[hidden email]> wrote:

> We are using the plain mybatis Resources, mybatis.xml and mybatis
> SqlSessionFactory etc.  The sql sessions are not shared with any other
> app.  When we run our tests, only our app is running against the DB.
> If we enable caching in our jackpot mapper, which has a select for
> update in it, it always hangs in the mybatis caching code.  However,
> if we enable only caching in other totaly harmless static classes also
> it sometimes hangs all threads in the same method: unsafe.park().  If
> we disable caching in every mapper, the app works perfectly with
> thousands of concurrent tests.  We only chache some selects based on
> time, where it doesnt matter if the data is slightly old (i.e. not
> balances or similar).
>
> Simon.
>
> On Jun 27, 2:50 pm, Larry Meadors <[hidden email]> wrote:
>> I'm using the built-in postgresql pool with the default cache without problems.
>>
>> Are you sharing your sql sessions or something?
>>
>> Larry
>>
>> On Mon, Jun 27, 2011 at 6:41 AM, Simon <[hidden email]> wrote:
>>> Bump?
>>
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Larry Meadors
In reply to this post by Simon
Like Jeff and Richard have said: We don't have enough information to
help you more.

If you can't give us enough code to reproduce it, we can't help you fix it.

If it only happens in your production system, and you can't share that
code, then you have two options - debug through it, or pay someone to
sign an NDA and help fix it.

Larry
Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Clinton Begin
Administrator
In reply to this post by Simon
The problem will be in the TransactionalCache and/or CachingExecutor classes that employ the Java 5 concurrency libraries.  

However, there are 3 data points that are important:

  * A lot of people use MyBatis caching,
  * This seems to be a rare or even unique issue based on the comments here, 
  * I had a quick search around the web for this problem elsewhere, and it doesn't seem to ever come down to an actual code issue.  It seems that it's been a bug in certain JVMs dating back to 5.0.

One post I found mentioned that Java 1.6 u21 might have fixed the issue.

But if you can find somewhere online that points to a way to cause this problem through a coded misuse of the library, please forward it along and I'll have a look to see if MyBatis could have the same issue.  

Cheers,
Clinton

On Tue, Jun 28, 2011 at 6:38 AM, Simon <[hidden email]> wrote:
We are using the plain mybatis Resources, mybatis.xml and mybatis
SqlSessionFactory etc.  The sql sessions are not shared with any other
app.  When we run our tests, only our app is running against the DB.
If we enable caching in our jackpot mapper, which has a select for
update in it, it always hangs in the mybatis caching code.  However,
if we enable only caching in other totaly harmless static classes also
it sometimes hangs all threads in the same method: unsafe.park().  If
we disable caching in every mapper, the app works perfectly with
thousands of concurrent tests.  We only chache some selects based on
time, where it doesnt matter if the data is slightly old (i.e. not
balances or similar).

Simon.

On Jun 27, 2:50 pm, Larry Meadors <[hidden email]> wrote:
> I'm using the built-in postgresql pool with the default cache without problems.
>
> Are you sharing your sql sessions or something?
>
> Larry
>
> On Mon, Jun 27, 2011 at 6:41 AM, Simon <[hidden email]> wrote:
> > Bump?
>

Reply | Threaded
Open this post in threaded view
|

Re: mybatis caching always hangs in "Unsafe.park". Any tips?

Clinton Begin
Administrator
PS:  If you're really in a bind, you could replace the J5 concurrency libs with the older approach of synch/wait/notify to implement the same guarded suspension pattern.  Previous versions of iBATIS did this.  It might even be possible to hide it behind a common interface so you could easily switch between the two.

Cheers,
Clinton 



On Wed, Jun 29, 2011 at 4:43 PM, Clinton Begin <[hidden email]> wrote:
The problem will be in the TransactionalCache and/or CachingExecutor classes that employ the Java 5 concurrency libraries.  

However, there are 3 data points that are important:

  * A lot of people use MyBatis caching,
  * This seems to be a rare or even unique issue based on the comments here, 
  * I had a quick search around the web for this problem elsewhere, and it doesn't seem to ever come down to an actual code issue.  It seems that it's been a bug in certain JVMs dating back to 5.0.

One post I found mentioned that Java 1.6 u21 might have fixed the issue.

But if you can find somewhere online that points to a way to cause this problem through a coded misuse of the library, please forward it along and I'll have a look to see if MyBatis could have the same issue.  

Cheers,
Clinton

On Tue, Jun 28, 2011 at 6:38 AM, Simon <[hidden email]> wrote:
We are using the plain mybatis Resources, mybatis.xml and mybatis
SqlSessionFactory etc.  The sql sessions are not shared with any other
app.  When we run our tests, only our app is running against the DB.
If we enable caching in our jackpot mapper, which has a select for
update in it, it always hangs in the mybatis caching code.  However,
if we enable only caching in other totaly harmless static classes also
it sometimes hangs all threads in the same method: unsafe.park().  If
we disable caching in every mapper, the app works perfectly with
thousands of concurrent tests.  We only chache some selects based on
time, where it doesnt matter if the data is slightly old (i.e. not
balances or similar).

Simon.

On Jun 27, 2:50 pm, Larry Meadors <[hidden email]> wrote:
> I'm using the built-in postgresql pool with the default cache without problems.
>
> Are you sharing your sql sessions or something?
>
> Larry
>
> On Mon, Jun 27, 2011 at 6:41 AM, Simon <[hidden email]> wrote:
> > Bump?
>