【发布时间】:2022-01-20 16:15:04
【问题描述】:
我有一个后端 Web API(AppService、.Net Core 3.0)访问的 Azure SQL 数据库, 两者都托管在同一个 Azure 区域中。
后端使用Dapper 查询/映射数据库中的数据。
只是正常的电话,例如:
connection.Query<...>
connection.QueryMultiple(...)
一切都很完美......但有时,会发生一些事情...... 通常当数据库处于高负载时,有时处于中等负载时..
查询开始随机失败并出现不同的错误:
System.InvalidOperationException: No columns were selected
System.ArgumentException: When using the multi-mapping APIs ensure you set the splitOn param
if you have keys other than Id (Parameter 'splitOn')
System.ApplicationException: Attempting to cast a DBNull to a non nullable type!
Note that out/return parameters will not have updated values until the data stream completes
(after the 'foreach' for Query(..., buffered: false), or after the GridReader has been
disposed for QueryMultiple)
最糟糕的是,有时根本没有错误,只返回空结果集 甚至是一些列值缺失的格式错误的结果。
我花了很多时间寻找原因,但没有运气。 问题主要是查询中的一些错误,这里不是这种情况。
我执行相同的简单查询 20 次,成功 15-16 次,错误 4-5 次。
一段时间后,一切恢复正常,一切正常。
我感觉 SQL 数据库出于某种原因正在返回损坏的数据, 但我不知道如何调查/追踪它???
我没有想法 - 非常欢迎任何提示检查/寻找什么
更新:
我可以看到这是 Dapper 引发前两个异常的代码:
private static Exception MultiMapException(IDataRecord reader)
{
bool hasFields = false;
try { hasFields = reader != null && reader.FieldCount != 0; }
catch { /* don't throw when trying to throw */ }
if (hasFields)
return new ArgumentException("When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id", "splitOn");
else
return new InvalidOperationException("No columns were selected");
}
所以可能会有更有意义的异常被空的catch 块吞噬。不知道有没有办法让我以某种方式看到那个?
这是@Charlieface 要求的示例:
CREATE PROCEDURE [dbo].[spDossierPhoto_Get]
(
@LanguageID nvarchar(20),
@PhotoID uniqueidentifier
)
AS
SELECT
photo.*
FROM
viewDossierPhoto AS photo
WHERE
(photo.DossierPhoto_LanguageID = @LanguageID) AND
(photo.DossierPhoto_PhotoID = @PhotoID)
RETURN
我再重复一遍 - 它与错误的语法、未执行的案例或任何愚蠢的错误没有任何关系......确切的代码,准确的一切,数百个这样的查询,未触及......正在运行一年多了,调用了数百万次都没有问题 - 最近开始失败并出现异常。
相同的参数,相同的查询,相同的一切......大部分时间都能完美运行,然后由于某种原因开始失败
【问题讨论】:
-
执行查询的单个 API 请求在单个线程中执行。甚至不使用
async和await,它们可能会在不同的线程上恢复。当然,有许多请求是并行执行的,就像任何其他 ASP.Net 应用程序一样。 -
嗯,我明白你的意思了,查询似乎没有问题。虽然不知道为什么你会在上面使用
QueryMultiple。您使用的是最新版本的 Dapper 吗?也许你可以设置一个断点(或捕获第一次机会异常)并观察在这种情况下实际数据正在经历什么 -
@Charlieface,谢谢,示例一通过
Query执行,其他一些返回多个结果集的SP 通过QueryMultiple调用。但无论如何 - 再次重复 - 所有这些工作都很好,直到开始发生一些事情并且......过了一会儿,恢复正常。有没有办法可以调试 Azure AppService(或至少记录一些东西)???因为,在开发环境中,问题是不可重现的...... -
可能相关:如果有人更改了视图,您需要使用
sp_refreshview重新编译它。因此,如果您有某种自动化系统可以删除和重新创建列或类似的,那可能就是问题
标签: sql-server azure asp.net-core