Tengo este extraño problema con nuestro software. Es está en producción durante 5 años y no hemos tenido este tipo de problemas ...consulta cuelga oráculo 10g
Problema:
Tenemos un trabajo de muelle (programador) que hace una consulta a través de hibernación, recupera los objetos y los modifica.
Bueno, esto funcionó durante varios años, pero hace un mes la consulta se cuelga 5-10 veces al día (la consulta se invoca cada 10 minutos). Y cuando se cuelga, tenemos que reiniciar el servicio.
El siguiente código hace la consulta:
@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
}
});
}
Fuente de datos se define como esto (sé que esto no se supone que es en la producción, pero esta es la única forma en que funciona - He intentado utilizar Oracle agrupación de conexiones, pero luego la consulta cuelga más a menudo ..):
<?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>
Software utilizado:
- primavera 1.2.7
- hibernación 3.0.5
- Oracle 10.2.0.1 (RAC)
- JDBC de Oracle 10.1.0.2
- Red Hat 3 EL
- Java 1.5_06
lo que he tratado de manera ahora:
- uso conjunto de conexiones de datos Oracle como fuente -> fracasaron con colgar conexiones
- utilizado JDBC de Oracle 10.2.0.5 -> pensé He resuelto que ... y después de unas horas se cuelguen de nuevo :(
No hay cerraduras de bases de datos Oracle en la medida de lo posible ver ...
¿Cuál podría ser el problema?
ACTUALIZACIÓN:
en el oráculo EM:
hallazgos ADDM: sentencias SQL que consumen tiempo importante base de datos se han encontrado. La consulta consume un tiempo de base de datos significativo. Impacto 81%. E/S de usuario espera 97%.
- sentencias SQL individuales responsables para el usuario significativo de E/S de espera eran encontrado.
- Segmentos de base de datos individuales responsables de la E/S de usuario significativo espera fueron encontrados.
- Se esperaba que el rendimiento del subsistema de E/S fuera significativamente menor que .
ACTUALIZACIÓN: (15.03.2011)
Por ahora el servicio funciona para casi 48 horas sin colgar.
soy escéptico de que esto va a resolver el problema, sino que lo hicieron algunos cambios en el código:
retira el decode(delivered,null,0,1) = 0
y decode(" + sqlCustAlias + ".deleteDate,null,1,0) = 1
funciones de consulta y los reemplazó con is null
declaraciones.
El campo entregado está indexado, pero la indexación no se puede usar en las funciones decode
.
¿Crees que esto es solo una coincidencia?
ACTUALIZACIÓN: (16.03.2011)
alert.log muestra ahora muchas entradas como esta:
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
Parece ser desde 3 días antes de las sesiones de 232.624 segundos ..!
+1 porque obviamente está trabajando el fin de semana para resolver un problema de producción. No hay horas extras en nuestra profesión, pero al menos hay un par de representantes :-) – corsiKa
muchas gracias. Los fines de semana están reservados para EMCY :-) – alesko
Mi experiencia ha sido que si algo estaba funcionando, pero ahora no lo es, es solo porque algo cambió. Este código no ha cambiado, lo que significa que sus datos probablemente sí lo hayan hecho. Ahora, conozco tanto sobre hibernación como esa roca de allí, así que no puedo analizar el código para encontrar el problema muy bien, pero analizaría lo que podría haber cambiado con los datos. Por supuesto, ya has superado eso, estoy seguro ... pero * encogerse de hombros * solo vale la pena mencionarlo. – corsiKa