首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查询挂起甲骨文10g

查询挂起甲骨文10g
EN

Stack Overflow用户
提问于 2011-03-12 19:09:55
回答 1查看 3.8K关注 0票数 13

我的软件有个奇怪的问题。我们已经生产了5年了,我们没有这样的问题.

问题:

我们有一个spring作业(调度器),它通过hibernate进行查询,检索对象并修改它们。

好吧,这几年起作用了,但一个月前,查询每天挂起5-10次(查询每10分钟调用一次)。当它挂起时,我们必须重新启动服务。

以下代码执行查询:

代码语言:javascript
复制
@SuppressWarnings("unchecked")
public List<Delivery> findScheduledForDelivery(final String inType, final int max, final String benefitType ) {


    //getHibernateTemplate().clear();

    return getHibernateTemplate().executeFind(new HibernateCallback() {
        public Object doInHibernate(Session session) throws SQLException {
            Criteria criteria = session.createCriteria(Delivery.class);

            criteria.createAlias("reward","r");
            criteria.createAlias("r.customer","c");
            criteria.createAlias("c.inNe","i");
            criteria.createAlias("r.promotion","p");
            criteria.createAlias("benefit","b");

            String sqlCustAlias = StringHelper.generateAlias("c", 2);

            criteria.add(Expression.disjunction()
                .add(Expression.eq("inStatus", INStatus.InterfaceFailure))
                .add(Expression.eq("inStatus",INStatus.Initial)));

            criteria.add(Expression.le("deliverAt", new Date()));

            String dateString = "2000/01/01";
            DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            Date startDate = new Date();
            try {
                startDate = dateFormat.parse(dateString);
                criteria.add(Expression.ge("deliverAt", startDate));
            }
            catch(ParseException e) {
                e.printStackTrace();
            }

            String sqlEqual = "decode(delivered,null,0,1) = 0";
            criteria.add(Expression.sql(sqlEqual));

            sqlEqual = "decode(" + sqlCustAlias + ".deleteDate,null,1,0) = 1";
            criteria.add(Expression.sql(sqlEqual));

            if(inType  != null ) {
                for(INType i : INType.values())
                    if(i.toString().equals(inType)) {
                        criteria.add(Expression.eq("i.inType", i));
                        break;
                    }
            }

            criteria.add(Expression.eq("p.active", true));

            if(benefitType != null) {
                if(benefitType.equals("FREECREDIT")) 
                    criteria.add(Expression.disjunction()
                            .add(Expression.eq("b.type", BenefitType.FREE_CREDIT))
                            .add(Expression.eq("b.type", BenefitType.FREE_CREDIT_FTAM)));
                else if(benefitType.equals("NONFREECREDIT")) {
                    criteria.add(Expression.conjunction()
                            .add(Expression.ne("b.type", BenefitType.FREE_CREDIT))
                            .add(Expression.ne("b.type", BenefitType.OTHER))
                            .add(Expression.ne("b.type", BenefitType.VOUCHER)));
                    criteria.add(Expression.isNull("b.md3Profile")); 
                }
                if(max != 0)
                    criteria.setMaxResults(max);
            }

            criteria.addOrder( Order.desc("p.priority") );
            criteria.addOrder( Order.asc("deliverAt") );



            return criteria.list(); <===== hangs here
        }
    });
}

数据源被定义为这样(我知道这不应该出现在生产中,但这是它工作的唯一方法--我试图使用oracle连接池,但是查询挂起的频率更高):

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="connectionProperties">
         <props>
          <prop key="tcp.nodelay">yes</prop>
          <prop key="delayRowPrefetch">20</prop>
          <prop key="defaultBatchSize">5</prop>
         </props>
        </property>
      </bean>
    </beans>

使用的软件:

1.2.7

  • hibernate 3.0.5

  • oracle 10.2.0.1 (RAC)

  • oracle 10.1.0.2

  • Red Hat 3 EL

H 113Java1.5_06H 214F 215

到目前为止我尝试过的是:

connections

  • used

  • 使用oracle连接池作为数据源->挂起-> oracleJDBC10.2.0.5->,我想我已经解决了.几个小时后,它又被绞死了:(

)

据我所知,甲骨文上没有数据库锁.

有什么问题吗?

更新:

在甲骨文中:

ADDM发现: SQL语句占用大量的数据库时间。查询消耗大量的数据库时间。影响81%。用户I/O等待97%。

负责重要用户I/O等待的found.

  • Individual数据库段是负责重要用户I/O等待的
  • 单个SQL语句,
  • 子系统的吞吐量明显低于预期。

更新:(15.03.2011)

目前,这项服务工作了将近48小时,没有上吊。

我对此表示怀疑,但我对代码做了一些修改:

删除查询中的decode(delivered,null,0,1) = 0decode(" + sqlCustAlias + ".deleteDate,null,1,0) = 1函数,并用is null语句替换它们。

交付的字段是索引的,但是索引不能在decode函数中使用。

你觉得这只是巧合吗?

更新:(16.03.2011)

alert.log现在显示了许多这样的条目:

代码语言:javascript
复制
ORA-01555 caused by SQL statement below (SQL ID: affkpm4j7azc4, Query Duration=232624 sec, SCN: 0x0003.dca70559):
Tue Mar 15 17:43:06 2011
select * from ( select this_.id as id5_, this_.deliverAt as deliverAt68_5_, this_.delivered as delivered68_5_, this_.inDelivery as inDelivery68_5_, this_.lastDeliveryTry as lastDeli5_68_5_, this_.tries as tries68_5_, this_.sentAt as sentAt68_5_, this_.sent as sent68_5_, this_.retry as retry68_5_, this_.inStatus as inStatus68_5_, this_.errorMessage as errorMe11_68_5_, this_.inCvsDelivery as inCvsDe12_68_5_, this_.cvsDelivered as cvsDeli13_68_5_, this_.cvsLastDeliveryTry as cvsLast14_68_5_, this_.cvsTries as cvsTries68_5_, this_.collectedPoints as collect16_68_5_, this_.smsMessage as smsMessage68_5_, this_.inOldStatus as inOldSt18_68_5_, this_.replacedDate as replace19_68_5_, this_.oldMsisdn as oldMsisdn68_5_, this_.deletedDate as deleted21_68_5_, this_.addManualDate as addManu22_68_5_, this_.stornoPromiseDate as stornoP23_68_5_, this_.stornoINDate as stornoI24_68_5_, this_.activationCode as activat25_68_5_, this_.activationExpirationDate as activat26_68_5_, this_.rewardId as rewardId68_5_, this_.benefitId as b

好像是三天前的会议。232624秒!

EN

回答 1

Stack Overflow用户

发布于 2011-03-12 19:56:44

首先,当此查询挂起时,请检查V$SESSION_WAIT以查看会话正在等待的内容。

第二个注意事项:上面显示的代码似乎忽略了max参数,除非benefitType参数是非空的。这是故意的吗?只有当benefitType参数为null时,查询才可能“挂起”吗?

对不起,我以为您在Oracle中有某种方法可以识别正确的会话。尝试这样的查询:

代码语言:javascript
复制
select v2.sid,
       v2.module,
       substr(v1.sql_text,1,180) sql_text,
       v1.rows_processed,
       v2.event,
       v2.seq#
from v$sqlarea v1, v$session v2
where v1.users_executing > 0
  and v2.sql_address (+) = v1.address;

这将显示当前正在执行的所有SQL,并在可能的情况下显示相关的会话ID以及它正在等待的事件。您应该能够使用SQL文本来标识您感兴趣的会话。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5284757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档