如何使用NHibernate和Spring为死锁配置RetryAdvice和ExceptionTranslation
我将Spring.net 1.2与NHibernate 2.0.1一起使用。如何使用NHibernate和Spring为死锁配置RetryAdvice和ExceptionTranslation,nhibernate,hibernate,spring,aop,spring.net,Nhibernate,Hibernate,Spring,Aop,Spring.net,我将Spring.net 1.2与NHibernate 2.0.1一起使用。 在我的项目中,我面临一些死锁问题,除了数据库调整以尽量减少死锁发生之外,我还想实现Springs RetryAdvice来处理这个问题。 我找不到任何关于如何配置此服务器的工作示例。参考资料似乎很清楚如何使用它,但不知何故,我无法让它工作 <!--Used to translate NHibernate exception to Spring.DataAccessExceptions--> <
在我的项目中,我面临一些死锁问题,除了数据库调整以尽量减少死锁发生之外,我还想实现Springs RetryAdvice来处理这个问题。
我找不到任何关于如何配置此服务器的工作示例。参考资料似乎很清楚如何使用它,但不知何故,我无法让它工作
<!--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中,但它无法工作。我不明白该把这个建议放在哪里。我是否必须声明一个切入点来添加它,或者如何才能使它按预期工作
Thx提前-感谢任何帮助。在等待有人解决我的问题一个半月后,我终于有时间自己详细说明解决方案。事实上,这并没有我想象的那么难。也许这就是为什么我找不到好的例子。 下面的测试将显示使用情况: 配置:(为了简洁起见,省略了SessionFactory和TransactionManager等)
任何提示或备注都非常感谢。要完成此操作,请执行以下操作:使用HibernateTemplate时,将自动实现例外翻译,就像我实际所做的那样。
<!-- 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>
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));
}