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

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

问题描述

我使用Spring.net 1.2与NHibernate 2.0.1。
在我的项目中,我面临一些死锁问题,除了数据库调整,以最大限度地减少发生我想实现Springs RetryAdvice处理此。

我找不到任何工作示例如何配置此。该参考似乎清楚如何使用它,但不知何故我无法得到它的工作。

 <! - 用于将NHibernate异常转换为Spring.DataAccessExceptions  - > 
< object type =Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor,Spring.Data/>

<! - ExceptionHandler对死锁执行重试 - >
< object name =ExceptionHandlingAdvicetype =Spring.Aspects.RetryAdvice,Spring.Aop>
< property name =retryExpressionvalue =关于异常名称DeadLockLoserException重试3倍速率(1 *#n + 0.5)/>
< / object>

我已将[Repository]属性添加到我的DAO以启用ExceptionTranslation并尝试添加RetryAdvice到我正在使用的TransactionProxyFactoryObject,但它不会工作。我不明白把这个建议放在哪里。我是否必须申报PointCut来添加它,或者如何让它按预期工作。



Thx提前 - 任何帮助表示赞赏。

解决方案

并等待有人解决我的问题半个月,我终于找到时间为自己阐述解决方案。事实上,我认为这并不困难。也许这就是为什么我无法找到任何好的例子。
所以我们来看看:下面的测试会显示用法:
$ b $ p配置:( SessionFactory和TransactionManager等为简洁起见省略)

 <! - 在DeadlockExceptions后重试Tx  - > 
< object name =ExceptionHandlingAdvicetype =Spring.Aspects.RetryAdvice,Spring.Aop>
< property name =retryExpressionvalue =关于异常名称DeadlockLoserDataAccessException重试3x延迟1s/>
< / object>

<! - 我们的DAO-MOCK的交易配置 - >
< object id =TxProxyConfigurationTemplateabstract =truetype =Spring.Transaction.Interceptor.TransactionProxyFactoryObject,Spring.Data>
< property name =PlatformTransactionManagerref =HibernateTransactionManager/>

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

< object id =MockDaoTxPFOparent =TxProxyConfigurationTemplate>
< property name =Targetref =MockDao/>
< / object>

<! - 基于DAO-Mock接口的ProxyFactoryObject - >
< object id =MockDaotype =Spring.Aop.Framework.ProxyFactoryObject,Spring.Aop>
< property name =proxyInterfacesvalue =RetryAdvice.IDaoMock/>
< property name =targetref =MockDaoImpl/>
< property name =interceptorNames>
< list>
<值> ExceptionHandlingAdvice< /值>
< / list>
< / property>
< / object>

<! - 模拟DAO实现 - >
< object id =MockDaoImpltype =RetryAdvice.DaoMock,RetryAdvice>
< constructor-arg name =maxExceptionCountvalue =2/>
< / object>

Mocked Dao:这个DAO会抛出DeadLockLooserExceptions两次,然后传递。

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

[存储库]
公共类DaoMock:IDaoMock
{
private int maxExceptionCount;
public int MethodCallCount {get;私人设置; }

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

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


$ / code $ / pre

测试:

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

任何提示或评论都可以使用。


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>

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.

解决方案

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:

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

The Test:

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

Any hints or remarks appreciated.

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

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