2010-03-15 5 views
5

Estoy usando Spring.net 1.2 con NHibernate 2.0.1.
Dentro de mi proyecto estoy enfrentando algunos problemas de interbloqueo y además de los ajustes de la base de datos para minimizar la ocurrencia, me gustaría implementar Springs RetryAdvice para manejar esto.
No encuentro ningún ejemplo práctico de cómo configurar esto. La referencia parece ser clara acerca de cómo usarla, pero de alguna manera no puedo hacer que funcione.Cómo configurar RetryAdvice y ExceptionTranslation para Deadlock usando NHibernate y Spring

<!--Used to translate NHibernate exception to Spring.DataAccessExceptions-->  
<object type="Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor, Spring.Data"/> 

<!--ExceptionHandler performing Retry on Deadlocks--> 
<object name="ExceptionHandlingAdvice" type="Spring.Aspects.RetryAdvice, Spring.Aop"> 
    <property name="retryExpression" value="on exception name DeadLockLoserException retry 3x rate (1*#n + 0.5)"/> 
</object> 

He añadido el atributo [Repositorio] a mis DAOs para obtener ExceptionTranslation activado y trataron de añadir el RetryAdvice a la TransactionProxyFactoryObject estoy usando pero no va a funcionar. No entiendo dónde poner este consejo. ¿Tengo que declarar un PointCut para agregarlo o cómo puedo hacerlo funcionar como se espera?

Thx de antemano - cualquier ayuda apreciada.

Respuesta

9

Después de 1 mes y medio de esperar a que alguien resolviera mi problema, finalmente encontré tiempo para elaborar la solución para esto solo. De hecho, no fue tan difícil, pensé que era. Tal vez por eso no pude encontrar ningún buen ejemplo. Así que aquí vamos: La siguiente prueba demostrará el uso:

Configuración: (SessionFactory y TransactionManager etc. omite por razones de brevedad)

<!-- Retries the Tx after DeadlockExceptions --> 
    <object name="ExceptionHandlingAdvice" type="Spring.Aspects.RetryAdvice, Spring.Aop"> 
    <property name="retryExpression" value="on exception name DeadlockLoserDataAccessException retry 3x delay 1s"/> 
    </object> 

    <!--A Transaction-Configuration for our DAO-MOCK--> 
    <object id="TxProxyConfigurationTemplate" abstract="true" type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data"> 
    <property name="PlatformTransactionManager" ref="HibernateTransactionManager"/> 

    <property name="TransactionAttributes"> 
     <name-values> 
     <add key="ThrowDeadLock*" value="PROPAGATION_REQUIRED"/> 
     </name-values> 
    </property> 
    </object> 

    <object id="MockDaoTxPFO" parent="TxProxyConfigurationTemplate"> 
    <property name="Target" ref="MockDao"/> 
    </object> 

    <!--The ProxyFactoryObject based on the DAO-Mock interface--> 
    <object id="MockDao" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop" > 
    <property name="proxyInterfaces" value="RetryAdvice.IDaoMock"/> 
    <property name="target" ref="MockDaoImpl"/> 
    <property name="interceptorNames"> 
     <list> 
     <value>ExceptionHandlingAdvice</value> 
     </list> 
    </property> 
    </object> 

    <!--Mocked DAO Implementation --> 
    <object id="MockDaoImpl" type="RetryAdvice.DaoMock, RetryAdvice"> 
    <constructor-arg name="maxExceptionCount" value="2" /> 
    </object> 

imitó Dao: Este DAO tirará DeadLockLooserExceptions dos veces y luego pasar.

public interface IDaoMock 
{ 
    void ThrowDeadLock(); 
    int MethodCallCount { get; } 
} 

[Repository] 
public class DaoMock : IDaoMock 
{ 
    private int maxExceptionCount; 
    public int MethodCallCount { get; private set; } 

    public DaoMock(int maxExceptionCount) 
    { 
     this.maxExceptionCount = maxExceptionCount; 
    } 

    public void ThrowDeadLock() 
    { 
     MethodCallCount++; 
     if (MethodCallCount <= maxExceptionCount) 
     { 
      throw new DeadlockLoserDataAccessException("FAKE", new HibernateException("This is a fake Exception.", null)); 
     } 
    } 

La prueba:

[Test] 
public void RetryAdviceTest() 
{ 
    IDaoMock mockDao = (IDaoMock)this.appContext.GetObject("MockDaoTxPFO"); 
    mockDao.ThrowDeadLock(); 
    Assert.That(mockDao.MethodCallCount, Is.EqualTo(3)); 
} 

Alguna pista o comentarios apreciados.

+0

Para completar esto: ExceptionTranslation se logra automáticamente cuando se utiliza HibernateTemplate como realmente lo hago. – zoidbeck

Cuestiones relacionadas