2010-03-15 2 views
5

NHibernate 2.0.1과 함께 Spring.net 1.2를 사용 중입니다.
일부 교착 상태 문제에 직면하고있는 상황에서이 문제를 최소화하기 위해 데이터베이스를 조정하는 것 외에는 Spring RetryAdvice를 구현하고 싶습니다.
작업 예제를 구성하는 방법을 찾을 수 없습니다. 참조를 사용하는 방법에 대한 명확한 것 같지만 어떻게 든 그것을 작동시키지 못할 수 있습니다.NHibernate 및 Spring을 사용하여 Deadlocks에 대해 RetryAdvice 및 ExceptionTranslation을 구성하는 방법

<!--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> 

내의 DAO에 [저장소] 속성을 추가 한이 ExceptionTranslation 활성화와 내가 사용하고있는 TransactionProxyFactoryObject에 RetryAdvice을 추가하려고하지만 그것은 작동하지 않습니다하세요. 나는이 충고를 어디에 둘 것인지 이해하지 못한다. 그것을 추가하기 위해 PointCut을 선언해야합니까, 아니면 예상대로 작동하도록 할 수 있습니까?

사전 - 도움을 주시면 감사하겠습니다.

답변

9

내 문제를 해결하는 누군가를 기다리는 1 개월 반 후, 마침내 혼자서 해결할 시간을 찾았습니다. 사실 그것은 그것이 어렵다고 생각하지 않았습니다. 어쩌면 내가 좋은 예를 찾을 수 없었던 것일 수도 있습니다. 그래서 여기에 우리가 간다 :

구성 : (등의 SessionFactory와 TransactionManager를 간결 생략)

<!-- 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> 

조롱 다오이 DAO 두 번 DeadLockLooserExceptions가 발생하고 전달합니다 다음 테스트 사용을 보여줍니다.

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)); 
     } 
    } 

테스트 : 감사

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

어떤 힌트 또는 발언.

+0

완료하려면 ExceptionTranslation은 실제로 HibernateTemplate을 사용할 때 자동으로 수행됩니다. – zoidbeck