2010-03-15 25 views
5

tôi đang sử dụng Spring.net 1.2 với NHibernate 2.0.1.
Trong dự án của tôi, tôi đang đối mặt với một số vấn đề về Deadlock và bên cạnh các chỉnh sửa cơ sở dữ liệu để giảm thiểu sự xuất hiện, tôi muốn triển khai Springs RetryAdvice để xử lý việc này.
Tôi không thể tìm thấy bất kỳ ví dụ hoạt động nào về cách định cấu hình này. Các tài liệu tham khảo có vẻ là rõ ràng về cách sử dụng nó, nhưng bằng cách nào đó tôi không thể làm cho nó hoạt động.Cách cấu hình RetryAdvice và ExceptionTranslation cho Deadlocks bằng cách sử dụng NHibernate và 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> 

Tôi đã thêm [Kho lưu trữ] thuộc tính để DAO tôi để ExceptionTranslation kích hoạt và cố gắng thêm các RetryAdvice đến TransactionProxyFactoryObject tôi đang sử dụng nhưng nó sẽ không hoạt động. Tôi không hiểu phải đưa ra lời khuyên này ở đâu. Tôi có phải tuyên bố một PointCut để thêm nó hoặc làm thế nào tôi có thể làm cho nó hoạt động như mong đợi.

Thx trước - bất kỳ trợ giúp nào được đánh giá cao.

Trả lời

9

Sau 1 tháng rưỡi chờ ai đó giải quyết vấn đề của mình, cuối cùng tôi đã tìm ra thời gian để tự mình giải quyết vấn đề này. Trong thực tế nó không phải là khó khăn tôi nghĩ rằng nó được. Có lẽ đó là lý do tại sao tôi đã không thể tìm thấy bất kỳ ví dụ tốt. Vì vậy, ở đây chúng tôi đi: Các thử nghiệm sau đây sẽ hiển thị cách sử dụng:

Cấu hình: (SessionFactory và TransactionManager, vv bỏ qua cho ngắn gọn)

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

chế giễu Đạo: DAO này sẽ ném DeadLockLooserExceptions hai lần và sau đó vượt qua.

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

Các thử nghiệm:

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

Bất kỳ gợi ý hoặc nhận xét đánh giá cao.

+0

Để hoàn thành việc này: ExceptionTranslation tự động đạt được khi sử dụng HibernateTemplate như tôi thực sự làm. – zoidbeck

Các vấn đề liên quan