如何在Nhibernate中复制并重试死锁 [英] how to replicate and retry deadlocks in nhibernate

查看:87
本文介绍了如何在Nhibernate中复制并重试死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看日志,可以发现我的应用容易受到死锁的影响.它们出现在我的应用程序的许多部分.

Looking through my logs, I can see that my app is vulnerable to deadlocks. They are occurring in many parts of my application.

1)有没有办法复制此问题.即:我只在日志中看到了这一点.

1) Is there way to replicate this issue. ie: I have only seen this in logs.

2)如果交易被锁定,最好/最简单的重试方法是什么

2) What is the best/simplest way to retry if the transaction is locked

3)如果我将通话包裹在try/catch中.什么是异常类型.

3) If I wrapped the call in a try/catch. What would the exception type be.

有很多关于这个问题的文章.我得出结论,最好的选择是尝试尽可能缩短交易时间.我应该更改隔离级别吗?

There is a lot written about the issue. I concluded the best option is to try and shorten the transactions as much as possible. Should I change the isolation levels?

推荐答案

查找死锁

死锁很难找到.如果您知道它们为什么会发生,则可以在集成测试中重现它.在实际环境中,您可以使用Profiler观察死锁.它显示了一个图形,该图形显示了死锁的形成方式.

Finding Deadlocks

deadlocks are very hard to find. If you know why they occur, you may reproduce it in integration tests. In real environments you can use Profiler to observe dead locks. It shows a graph which displays how the deadlock is formed.

您实际上应该放弃交易,然后重新开始.发生数据库异常后,NHibernate会话将不同步.

You should actually throw away the transaction and start again. The NHibernate session is out of synch after any database exception.

我们在重新启动之前有一个延迟,以避免对数据库造成更大的压力.它会等待一段时间,其中包含一个随机数,以避免并行事务再次同步.

We have a delay before restarting to avoid more stress to the database. It waits for a certain time containing a random number, to avoid that the parallel transactions are synchronizing again.

减少锁定时间

如果使用的是Sql Server,则由于其悲观的锁定机制(与Oracle数据库相反),它很容易死锁.较新的Snapshot隔离级别类似于Oracle所做的事情,并且可以在某种程度上解决该问题,但是我直到现在都没有使用过,所以我对此不多说.

If you are using Sql Server, it is very vulnerable to dead locks because of its pessimistic locking mechanism (in contrast to Oracle databases). The newer Snapshot isolation level is something similar to what Oracle is doing and may fix the problem to some degree, but I never used until now so I can't say much about it.

NHibernate通过将对更改的持久性数据进行缓存并将其存储在事务结束时,尽可能地解决了该问题.但是有一些限制和打破它的方法.

NHibernate fixes the problem as far as possible by caching changes to persistent data and store it at the end of a transaction. But there are some limits and some ways to break it.

使用身份(自动编号")作为主键可能是

Using identity ("auto numbers") as primary keys is probably the most famous mistake. It forces NH to insert entities when they are put into the session which produces a lock of the whole table (in SQL Server).

更容易解决的是冲洗问题. NH需要在执行查询之前刷新更改,以确保一致性.您可以通过将FlushMode设置为Never来解决此问题,这可能会导致一致性问题,因此只有在完全了解自己的操作后才执行此操作.最好的解决方案是仅使用GetLoad或导航到根实体的属性,而不是在事务中间执行查询.

More complicated to fix is the flushing problem. NH needs to flush changes before executing queries, to ensure consistency. You can get around this by setting FlushMode to Never, which may cause consistency problems, so only do it when you exactly know what you do. The best solution is to only use Get or Load or navigate to properties of a root entity instead of performing queries in the middle of a transaction.

通过所有这些操作,NH可以等待对数据库的任何Insert,Update和Delete命令,直到事务结束.大大减少了锁定时间,因此也降低了死锁的风险.

By doing all this, NH is able to wait for any Insert, Update and Delete command to the database until the end of the transaction. The reduces lock time a lot and therefore it also reduces the risk of dead locks.

避免死锁的一般规则

使用NHibernate时,也适用避免死锁的一般规则.最重要的是:按一定顺序锁定资源,而不是一开始就锁定资源,而是一开始就锁定所有资源.后者与我上面所说的减少锁定时间是矛盾的.这意味着您需要在事务开始时锁定资源,以使其他事务等待其完成.这样可以减少死锁,但也可以减少并行执行.

The general rules to avoid deadlocks also apply when using NHibernate. Most important: lock resources in a certain order, lock resources not on by one but all at the beginning. The latter is contradictory to what I said above to reduce lock time. It would mean that you lock resources at the beginning of a transaction to make other transactions wait until it is finished. This may reduce deadlocks but also reduces parallel execution.

这篇关于如何在Nhibernate中复制并重试死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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