插入时MyBatis挂起

时间:2015-08-05 21:59:59

标签: mybatis spring-mybatis

我正在尝试使用MyBatis-Spring将记录插入Oracle 11g数据库,但插件挂起。选择工作正常。

我需要另一双眼睛来帮助我弄清楚发生了什么。

以下是重要的代码片段:

记录输出:(它永远挂在最后一行)

Running persistence.PartyMapperUnitTest
DEBUG [main] - Cache Hit Ratio [persistence.mapper.PartyMapper]: 0.0
DEBUG [main] - ==>  Preparing: SELECT PARTY_ID, PARTY_SUBTYPE_CD, LIFECYCLE_CD, PARTY_STATUS_CD FROM PARTY WHERE PARTY_ID =2 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
DEBUG [main] - ==>  Preparing: INSERT INTO PARTY (PARTY_SUBTYPE_CD, LIFECYCLE_CD, PARTY_STATUS_CD, CREATED_BY) VALUES (?,?,?,?) 
DEBUG [main] - ==> Parameters: partySubtypeCode1438810529048(String), lifecycleCode(String), partyStatusCode(String), createdBy(String)
***==== The application hangs forever at this log line ====***

Testing.sql (这很好用)

INSERT INTO PARTY (PARTY_SUBTYPE_CD, LIFECYCLE_CD, PARTY_STATUS_CD, CREATED_BY)
VALUES ( 'a', 'b', 'c', 'd');

的applicationContext.xml

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
</bean>

PartyMapper.java

public interface PartyMapper<PartyEntity> {
    public PartyEntity fetch(Object entityId);
    public int insert(PartyEntity entity);
}

PartyMapper.xml

<insert
    id="insert"
    parameterType="persistence.entity.PartyEntity"
    keyProperty="partyId"
    keyColumn="PARTY_ID"
    useGeneratedKeys="true">
    INSERT INTO PARTY
        (PARTY_SUBTYPE_CD, LIFECYCLE_CD, PARTY_STATUS_CD, CREATED_BY)
    VALUES
        (#{partySubtypeCode},#{lifecycleCode},#{partyStatusCode},#{createdBy})
</insert>

PartyMapperUnitTest.java

PartyEntity expectedParty = new PartyEntity();
expectedParty.setPartySubtypeCode("a");
expectedParty.setLifecycleCode("b");
expectedParty.setPartyStatusCode("c");
expectedParty.setCreatedBy("d");
partyMapper.insert(expectedParty);

===编辑=== UnitTest运行时只运行两个线程。我在这里没有看到任何错误。

在插入之前添加了一个Thread.dumpStack(),但没有看到任何错误:

Thread.dumpStack()

INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@77ab3f0: defining beans [transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,sqlSessionFactory,dataSource,org.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,mapper,partyMapper,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
java.lang.Exception: Stack trace
    at java.lang.Thread.dumpStack(Thread.java:1365)
    at td.com.naccms.cps.persistence.PartyMapperUnitTest.insert(PartyMapperUnitTest.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
...
...

1 个答案:

答案 0 :(得分:2)

您的连接池中有多少个连接?我经常看到这种情况经常发生在数据库池有1个连接并且有2个并发事务时(因此MyBatis无法获得数据库连接,而jdbc连接池实际上是挂起的)。您可以调试您的应用并暂停&#39;它什么时候挂起来。您应该能够看到线程并跟踪哪个ID被阻塞以及在哪里。另一种选择,但更罕见的是,该表被锁定。您可以谷歌查询一些查询,这些查询将向您显示数据库中的所有当前锁定。

在您的评论后编辑

为了在发生这种情况时出现错误,我的建议是在mybatis中设置defaultStatementTimeout。这至少会引发异常,而不是永远挂起。

您也可能希望在数据库连接池中配置一些超时,因为某些池默认情况下会永远等待(这是一个漫长的时间:)。