如何使用 NHibernate 和 Spring 为死锁配置 RetryAdvice 和 ExceptionTranslation [英] How to configure RetryAdvice and ExceptionTranslation for Deadlocks using NHibernate and Spring

查看:28
本文介绍了如何使用 NHibernate 和 Spring 为死锁配置 RetryAdvice 和 ExceptionTranslation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Spring.net 1.2 和 NHibernate 2.0.1.
在我的项目中,我面临一些死锁问题,除了数据库调整以尽量减少发生率之外,我还想实施 Springs RetryAdvice 来处理这个问题.
我找不到任何如何配置 this 的工作示例.参考文献似乎很清楚如何使用它,但不知何故我无法让它工作.

i am using Spring.net 1.2 with NHibernate 2.0.1.
Within my project i'am facing some Deadlock issues and besides the database tweaks to minimize the occurence i would like to implement Springs RetryAdvice to handle this.
I can't find any working example how to configure a this. The reference seems to be clear about how to use it but somehow i can't get it working.

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

我已将 [Repository] ​​属性添加到我的 DAO 以启用 ExceptionTranslation,并尝试将 RetryAdvice 添加到我正在使用的 TransactionProxyFactoryObject,但它不起作用.我不明白把这个建议放在哪里.我是否必须声明一个 PointCut 来添加它,或者我怎样才能让它按预期工作.

I have added the [Repository] attribute to my DAOs to get ExceptionTranslation enabled and tried to add the RetryAdvice to the TransactionProxyFactoryObject i am using but it won't work. I don't understand where to put this Advice. Do i have to declare a PointCut to add it or how could i get it to work as expected.

提前感谢 - 感谢任何帮助.

Thx in advance - any help appreciated.

推荐答案

在等待有人解决我的问题 1 个半月后,我终于有时间自己详细说明解决方案.事实上,这并没有我想象的那么难.也许这就是为什么我找不到任何好的例子.所以我们开始:以下测试将显示用法:

After 1 and a half month of waiting for someone solving my problem i finally found time to elaborate the solution for this by myself. In fact it wasn't that difficult i thought it was. Maybe thats why i wasn't able to find any good example. So here we go: The following test will show the usage:

配置:(为简洁起见省略了SessionFactory和TransactionManager等)

Configuration: (SessionFactory and TransactionManager etc. omitted for brevity)

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

Mocked Dao:这个 DAO 会抛出 DeadLockLooserExceptions 两次然后通过.

Mocked Dao: This DAO will throw DeadLockLooserExceptions twice and then pass.

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

感谢任何提示或评论.

这篇关于如何使用 NHibernate 和 Spring 为死锁配置 RetryAdvice 和 ExceptionTranslation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆