Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 通过NHibernate查询SQL Server时超时_Sql Server_Nhibernate_Locking - Fatal编程技术网

Sql server 通过NHibernate查询SQL Server时超时

Sql server 通过NHibernate查询SQL Server时超时,sql-server,nhibernate,locking,Sql Server,Nhibernate,Locking,我有一个ASP.NETMVC应用程序,它通过NHibernate使用SQLServer2005。我偶尔收到以下错误消息: “System.Data.SqlClient.SqlException(0x80131904):超时已过期。 在完成操作或操作之前经过的超时时间 服务器没有响应。位于 System.Data.SqlClient.SqlConnection.OnError(SqlException异常, 布尔断开连接)在 System.Data.SqlClient.SqlInternalCon

我有一个ASP.NETMVC应用程序,它通过NHibernate使用SQLServer2005。我偶尔收到以下错误消息:

“System.Data.SqlClient.SqlException(0x80131904):超时已过期。 在完成操作或操作之前经过的超时时间 服务器没有响应。位于 System.Data.SqlClient.SqlConnection.OnError(SqlException异常, 布尔断开连接)在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔断开连接)位于 System.Data.SqlClient.TdsParser.throweexception和warning()位于 System.Data.SqlClient.TdsParser.Run(RunBehavior, SqlCommand cmdHandler、SqlDataReader数据流、, BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject (b)在 System.Data.SqlClient.SqlDataReader.SetMetaData(_SqlMetaDataSet 元数据,Boolean moreInfo)位于 System.Data.SqlClient.TdsParser.Run(RunBehavior, SqlCommand cmdHandler、SqlDataReader数据流、, BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)位于System.Data.SqlClient.SqlDataReader.ConsumerMetadata()处 位于System.Data.SqlClient.SqlDataReader.get_MetaData()处 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, 运行行为运行行为,字符串重置选项字符串)位于 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior、Boolean returnStream、Boolean 异步)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、布尔返回流、字符串 方法,DbAsyncResult(结果)位于 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、布尔返回流、字符串 方法)在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法)在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为)在 System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
在NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
在NHibernate.Loader.Loader.GetResultSet(IDBST命令,布尔值 自动发现转换类型、布尔可调用、行选择、, ISessionImplementor会话)在 NHibernate.Loader.Loader.DoQuery(ISessionImplementor会话, QueryParameters QueryParameters,布尔返回代理)位于 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor 会话,查询参数,查询参数,布尔返回代理)
在NHibernate.Loader.Loader.DoList(ISessionImplementor会话, 查询参数查询参数“

大多数情况下,系统工作正常,响应速度非常快。我已经查看了系统上的锁,我通常会发现一个查询被另一个查询阻塞:

"SELECT TOP 10 d.Id, d.Name FROM Documents d INNER JOIN Users u ON..."
正在被以下内容阻止:

"SELECT TOP 10 Id, Name FROM Users"
查看blocking语句所持有的锁,在与Users表无关的各种表上大约有十几个排他(X)和(IX)页锁和键锁(但它们是被阻止的查询的一部分)


此处不涉及更新、插入或删除-因此,为什么一个只读查询会阻止另一个,为什么对Users表的简单查询会导致许多其他表被锁定。

这会导致问题:

begin transaction 

update Documents
set SomeField = 'SomeValue'
where SomeCondition = 'XXXX'

select top 10 Id, Name from Users

commit
在更新期间在文档表上创建的锁在提交事务之前不会被释放。这意味着一个连接可以将select语句作为其最近的语句,但仍然持有来自上一次更新的锁

一些想法:

  • 确保您正在提交/回滚事务
  • 尝试缩短事务的长度(例如,在上面的示例中,在运行select之前提交是否安全?)
  • 通过确保外键被索引来优化更新时的连接也可能会加快事务的速度
  • 请注意,select本身只会生成共享锁


    最后要注意(nolock)锁提示的想法。读取未提交的数据很少是个好主意。

    这会导致以下问题:

    begin transaction 
    
    update Documents
    set SomeField = 'SomeValue'
    where SomeCondition = 'XXXX'
    
    select top 10 Id, Name from Users
    
    commit
    
    在更新期间在文档表上创建的锁在提交事务之前不会被释放。这意味着一个连接可以将select语句作为其最近的语句,但仍然持有来自上一次更新的锁

    一些想法:

  • 确保您正在提交/回滚事务
  • 尝试缩短事务的长度(例如,在上面的示例中,在运行select之前提交是否安全?)
  • 通过确保外键被索引来优化更新时的连接也可能会加快事务的速度
  • 请注意,select本身只会生成共享锁


    最后要注意(nolock)锁提示的想法。读取未提交的数据很少是个好主意。

    SQL Server gotcha是数据库上的非默认“隔离级别”设置。SQL Server的默认隔离级别(锁定策略)为ReadCommitted,这意味着读锁会尽快释放,但写锁在事务提交之前不会释放。在Andy的回答中,默认隔离级别将导致select被阻止。但是,如果数据库设置为RepeatableRead或Serializable,则selects将在事务期间始终相互阻止。可以使用以下hibernate.cfg.xml配置在NHibernate中控制此设置:

    <session-factory>
        ...
        <add key="hibernate.connection.isolation" value="ReadCommitted" />
        ...
    </session-factory>
    
    
    ...
    ...
    
    SQL Server gotcha是数据库上的非默认“隔离级别”设置。SQL Server的默认隔离级别(锁定策略)为ReadCommitted,这意味着读锁会尽快释放,但写锁在事务完成之前不会释放