Sql server 2008 多连接情况下的NHibernate查询死锁
我有下一笔交易:Sql server 2008 多连接情况下的NHibernate查询死锁,sql-server-2008,nhibernate,deadlock,Sql Server 2008,Nhibernate,Deadlock,我有下一笔交易: Desc d = new Desc(); d.Descr = "new"; _sess.Transaction.Begin(); _sess.SaveOrUpdate(d); var desc = _sess.CreateCriteria(typeof(Desc)).List<Desc>(); _sess.Transaction.Commit(); 当我在两个进程中执行此代码时,会出现死锁,因为 1过程 执行插入并锁定钥匙 2过程
Desc d = new Desc();
d.Descr = "new";
_sess.Transaction.Begin();
_sess.SaveOrUpdate(d);
var desc = _sess.CreateCriteria(typeof(Desc)).List<Desc>();
_sess.Transaction.Commit();
当我在两个进程中执行此代码时,会出现死锁,因为
1过程
执行插入并锁定钥匙
2过程
执行插入并锁定钥匙
1进程希望在超时状态下执行选择和传递
2进程希望在超时状态下执行选择和传递
结果:僵局
BD:MS SQL Server 2008 R2
2个问题:
USE Test
BEGIN TRANSACTION
SELECT TOP 1 Id FROM [Desc] (UPDLOCK)
INSERT INTO [Desc] (Descr) VALUES ('33333')
SELECT * FROM [Desc]
COMMIT TRANSACTION
SELECT TOP 1 Id FROM [Desc] (UPDLOCK)
我如何在以下帮助下执行:
USE Test
BEGIN TRANSACTION
SELECT TOP 1 Id FROM [Desc] (UPDLOCK)
INSERT INTO [Desc] (Descr) VALUES ('33333')
SELECT * FROM [Desc]
COMMIT TRANSACTION
SELECT TOP 1 Id FROM [Desc] (UPDLOCK)
?我会将事务更改为快照。这避免了读取数据时的锁定,允许更多的并发性,尤其是在只读事务中没有死锁
出现死锁的原因如下:insert不相互冲突。它们锁定新插入的行。但是,查询被锁定,因为它试图从另一个事务读取新插入的行。因此,两个查询都在等待另一个事务完成,这是一个死锁。对于隔离级别快照,查询根本不关心未提交的行。它不等待释放锁,而是只“查看”已提交的行。这避免了查询中的死锁。为什么var desc=_sess.CreateCriteria(typeof(desc)).List();包括在交易中?我对我来说没有意义。。。这只会引起麻烦。这只是一个简单的例子。生活中的交易更复杂,谢谢!但如果我将事务隔离级别更改为快照,并且事务确实回滚,我将得到错误的数据,对吗?这不太好,嗯?为什么要获取错误的数据?使用任何类型的事务隔离的原因是,您不关心其他事务,不管它们最终是提交还是回滚。第一个事务不插入2。第二个事务不插入3。第一个事务不选择*4。第二个事务回滚,结果是:第一个事务将返回第二个事务回滚时删除的行。我们将得到错误的数据。不!第一个事务从未看到任何其他人未提交的内容。同样,这被称为隔离。你说的是完全关闭锁定(也称为read uncommitted),这是一件非常糟糕的事情。但是,如果我使用“Transaction.Begin(IsolationLevel.Snapshot)”,我会得到异常:“快照隔离事务访问数据库“测试”失败,因为此数据库中不允许快照隔离。使用ALTER DATABASE允许快照隔离。“如果我执行以下操作:“ALTER DATABASE TEST SET READ_COMMITED_snapshot ON”,我会得到数据不正确的情况。我会犯什么错误?