当我们上周五发布时,我收到了一个错误,我在接受时没有得到它的认可。错误信息是:
could not execute update query[SQL: delete from dbo.MyTable where col1=? and col2=? and col3=? and col4=? and col5=?]
我的C#代码如下:
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."}
发布于 2016-03-23 15:03:56
解决死锁可能是一件困难的事情,特别是在使用ORM时。死锁通常是因为数据库对象上的锁不是由不同的进程(或线程)以相同的顺序获得的,从而导致它们彼此等待。
ORM不给您太多的控制锁定获取订单。您可以重做查询顺序,但这可能会很乏味。特别是当缓存导致其中一些不访问DB时。此外,在使用相同数据库的任何其他应用程序上,都应该使用相同的顺序。
您可以检测死锁错误并执行消息所述的操作:重试整个过程。使用NHibernate,这意味着放弃当前会话并重新尝试整个工作单元。
如果您的数据库是Server,则会有一个大大增加死锁风险的默认设置:禁用读取提交快照模式。如果数据库中禁用了死锁,则可以通过启用死锁来大大降低死锁风险。此模式允许读取已提交隔离级别下的读取停止发出读锁。
您可以用
select snapshot_isolation_state_desc, is_read_committed_snapshot_on
from sys.databases
where name = 'YourDbName'您可以使用
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) )。
您还应该检查所有使用数据库的应用程序当前使用的隔离模式:其中一些模式是否使用比实际需要的更高的隔离级别?(如果可能,应该避免使用RepeatableRead和Serializable )。这是一个耗时的过程,因为它需要很好地理解隔离级别,同时研究每个用例以确定什么是适当的最小隔离级别。
https://stackoverflow.com/questions/36171956
复制相似问题