首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate IStatelessSession CreateQuery故障

NHibernate IStatelessSession CreateQuery故障
EN

Stack Overflow用户
提问于 2016-03-23 07:19:30
回答 1查看 326关注 0票数 0

当我们上周五发布时,我收到了一个错误,我在接受时没有得到它的认可。错误信息是:

could not execute update query[SQL: delete from dbo.MyTable where col1=? and col2=? and col3=? and col4=? and col5=?]

我的C#代码如下:

代码语言:javascript
复制
var hqlDelete = "DELETE MyTable m WHERE m.Col1 = :var_1 AND m.Col2 = :var_2 AND m.Col3= :var_3 AND m.Col4 = :var_4 AND m.Col5= :var_5";
var deletedEntities = session.CreateQuery(hqlDelete)
                             .SetString("var_1", variable1)
                             .SetString("var_2", variable2)
                             .SetString("var_3", variable3)
                             .SetString("var_4", variable4)
                             .SetString("var_5", variable5)
                             .ExecuteUpdate();
transaction.Commit();
session.Close();

现在,正如我所说,在验收测试时,错误并没有触发。此外,当我用生产数据库(从我的开发人员座位上的代码)进行测试时,它的工作也没有问题。

当我调用一个web服务并向它发布一个“度量”时,代码就会被触发。唯一的区别是,我在测试时调用该服务,而在生产时,另一家公司向web服务发送测量结果。

我认为这可能与会话/事务的数量有关,但这并不能真正解释为什么变量在错误消息中显示为?

有什么想法吗?我能提供更多的信息吗?你能帮我做这个吗?

编辑: InnerExeption是

{"Transaction (Process ID 68) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction."}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-23 15:03:56

解决死锁可能是一件困难的事情,特别是在使用ORM时。死锁通常是因为数据库对象上的锁不是由不同的进程(或线程)以相同的顺序获得的,从而导致它们彼此等待。

ORM不给您太多的控制锁定获取订单。您可以重做查询顺序,但这可能会很乏味。特别是当缓存导致其中一些不访问DB时。此外,在使用相同数据库的任何其他应用程序上,都应该使用相同的顺序。

您可以检测死锁错误并执行消息所述的操作:重试整个过程。使用NHibernate,这意味着放弃当前会话并重新尝试整个工作单元。

如果您的数据库是Server,则会有一个大大增加死锁风险的默认设置:禁用读取提交快照模式。如果数据库中禁用了死锁,则可以通过启用死锁来大大降低死锁风险。此模式允许读取已提交隔离级别下的读取停止发出读锁。

您可以用

代码语言:javascript
复制
select snapshot_isolation_state_desc, is_read_committed_snapshot_on
    from sys.databases 
    where name = 'YourDbName'

您可以使用

代码语言:javascript
复制
alter database YourDbName
    set allow_snapshot_isolation on

alter database YourDbName
    set read_committed_snapshot on

这要求在目标db上不运行任何事务。当然,这需要DB上的管理权限。

在我无法选择更改此设置的应用程序上,我不得不采用一种更奇怪的方式:将NHibernate默认隔离模式(配置参数)设置为ReadUncommitted。我的应用程序大多是只读的,并且在少数需要读取然后写入数据的事务上,我显式地提升了隔离模式(通过示例使用session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted) )。

您还应该检查所有使用数据库的应用程序当前使用的隔离模式:其中一些模式是否使用比实际需要的更高的隔离级别?(如果可能,应该避免使用RepeatableReadSerializable )。这是一个耗时的过程,因为它需要很好地理解隔离级别,同时研究每个用例以确定什么是适当的最小隔离级别。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36171956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档