我有时会在生产环境中遇到SqlCommand.ExecuteScalar()
返回NULL
。
我在这里遇到了很多类似的问题,最接近的问题是:SqlCommand.ExecuteScalar returns null but raw SQL does not。但给出的建议与我的情况无关。
代码示例在这里:
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT NEXT VALUE FOR Seq_Revision";
command.CommandType = CommandType.Text;
return (long)command.ExecuteScalar(); //<---ExecuteScalar() here returns NULL sometimes
}
}
Seq_Revision
这里是简单的MSSQL序列,如下所示:
CREATE SEQUENCE [dbo].[Seq_Revision]
AS [bigint]
START WITH 0
INCREMENT BY 1
MINVALUE -9223372036854775808
MAXVALUE 9223372036854775807
CACHE 10
GO
我非常确定它永远不会真正返回NULL。
此代码示例中返回NULL
时,我发现类似的奇怪(不可重复的行为),而我确定是具有此ID的实体:< / p>
NHibernate.ISession.Get<FooEntity>(entityId)
有趣的是,通过此方法返回NULL
与SQL节点上磁盘活动较多(磁盘队列长度> ~50)时的时间范围相关。 / p>
可能很重要:我们使用带有2个节点的AlwaysON群集,其中一个节点用于读取模式(连接字符串中为ApplicationIntent=READONLY
)。
MSSQL版本是:
Microsoft SQL Server 2014 (SP2-CU5) (KB4013098) - 12.0.5546.0 (X64)
Apr 3 2017 14:55:37
Copyright (c) Microsoft Corporation
Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: )
答案 0 :(得分:2)
我认为问题可能与序列缓存有关。
可能有一些未处理的东西会导致缓存中遗留的序列号丢失。
尝试在序列中禁用缓存:
ALTER SEQUENCE [dbo].[Seq_Revision]
NO CACHE
GO
或尝试使用更高的值来缓存:
ALTER SEQUENCE [dbo].[Seq_Revision]
CACHE 100
GO