Hello All.
I have an application that uses several session EJB's with remote access.
Two ejb's open a session (different session factories, different session, same jta transaction) and access the same table. The problem is that the session in one ejb blocks the access on the other. So the application hangs.
I temporarily solved the problem bringing the code that blocks to the first ejb, so, there are one single session accesing the BD.
Is there a way that the two different session's don't blocks each other?
I'm using spring with hibernate. And Spring hibernate classes. Also I'm using Spring's declarative transaction demarcation.
I'd Really appreciate your help.
LapKnight
Here is my configuration:
Hibernate Session Factory config of the first ejb:
<!-- SESSIONFACTORY -->
<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/dcv/cp/logica/mp/hib/HibBranch.hbm.xml</value>
<value>com/dcv/cp/logica/insope/hib/HibInstruccionOperacion.hbm.xml</value>
<value>com/dcv/cp/logica/mp/MedioPago.hbm.xml</value>
<value>com/dcv/cp/logica/mp/hib/HibAplica.hbm.xml</value>
<value>com/dcv/cp/moneda/dao/impl/Moneda.hbm.xml</value>
<value>com/dcv/cp/logica/ip/impl/InstruccionPago.hbm.xml</value>
<value>com/dcv/cp/logica/ip/impl/InstruccionPagoHistorica.hbm.xml</value>
<!-- <value>com/dcv/cp/oper/hibernate/Txpelq.hbm.xml</value>-->
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.SybaseDialect
transaction.factory_class=org.hibernate.transaction.BMTTransactionFactory
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
hibernate.current_session_context_class=org.hibernate.context.JTASessionContext
hibernate.connection.release_mode=after_statement
hibernate.transaction.flush_before_completion=true
hibernate.transaction.auto_close_session=true
hibernate.current_session_context_class=jta
TransactionStrategy=org.hibernate.transaction.JTATransactionFactory
</value>
</property>
</bean>
Hibernate Session Factory config of the second ejb:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/dcv/cp/oper/hibernate/Txpelq.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.SybaseDialect
transaction.factory_class=org.hibernate.transaction.BMTTransactionFactory
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
hibernate.current_session_context_class=org.hibernate.context.JTASessionContext
hibernate.connection.release_mode=after_statement
hibernate.transaction.flush_before_completion=true
hibernate.transaction.auto_close_session=true
hibernate.current_session_context_class=jta
TransactionStrategy=org.hibernate.transaction.JTATransactionFactory
</value>
</property>
</bean>
Blocking code:
private Collection getTxpelqs(Integer parte, Integer contraparte, Date fecha, Collection claves)throws Exception{
Collection txpelqs = new ArrayList();
Session sesion = this.getSessionFactory().getCurrentSession();
Query query = sesion.createSQLQuery(
"Select tx.*,a.numpgo " +
"from TXPELQ tx, CUENTAS cu, APLICA a " + <- conflict table ( APLICA)
"where tx.cuenta = cu.ctadep and " +
" tx.concta/1000 = :contraparte1 and " +
" tx.fecliq = :fecliq1 and " +
" tx.claope in (:claves1) and " +
" cu.coddep = :parte1 and " +
" tx.fecliq *= a.fecliq and " +
" tx.numope *= a.numope " +
"UNION " +
"Select tx.*,a.numpgo " +
"from TXPELQ tx, CUENTAS cu, APLICA a " +
"where tx.concta = cu.ctadep and " +
" tx.cuenta/1000 = :contraparte2 and " +
" tx.fecliq = :fecliq2 and " +
" tx.claope in (:claves2) and " +
" cu.coddep = :parte2 and " +
" tx.fecliq *= a.fecliq and " +
" tx.numope *= a.numope " +
" order by FECOPE, tx.OPEORI, CLAOPE, DIFMOV, OPEMOV").addEntity(Txpelq.class).addScalar("numpgo",Hibernate.INTEGER);
query.setInteger("contraparte1",contraparte.intValue());
query.setInteger("fecliq1",Fecha.getFechaInt(fecha,Fecha.AAAAMMDD).intValue());
query.setParameterList( "claves1", claves);
query.setInteger("parte1",parte.intValue());
query.setInteger("contraparte2",contraparte.intValue());
query.setInteger("fecliq2",Fecha.getFechaInt(fecha,Fecha.AAAAMMDD).intValue());
query.setParameterList( "claves2", claves);
query.setInteger("parte2",parte.intValue());
List operacionesTxpelq = query.list();
Iterator i = operacionesTxpelq.iterator();
while (i.hasNext()){
Object[] fila = (Object[])i.next();
Txpelq txpelq = (Txpelq)fila[0];
Integer codigo = (Integer)fila[1];
txpelq.setCodigoOperacion(codigo);
txpelqs.add(txpelq);
}
// sesion.close();
this.releaseSession(sesion);
return txpelqs;
}
Blocked code:
private int desaplicarMedioPago(MedioPago medioPago){
String hql = "delete from APLICA where numpgo = :numpgo and fecliq = :fecliq";
Query query = this.getSession().createSQLQuery(hql);
query.setInteger("numpgo",medioPago.getCodigo().intValue());
query.setInteger("fecliq",medioPago.getFechaLiquidacion().intValue());
int rowCount = query.executeUpdate();
System.out.println("Se eliminaron:[" + rowCount + "] registros");
return rowCount;
}
|