我开发了一个在Azure SQL数据库中存储数据的C#应用程序。
您可能知道,Azure SQL数据库位于Internet上的某个位置。不是通过LAN网络(但这个问题也与LAN等可靠网络有关)。
我注意到我不时会收到“连接已关闭”(或其他网络错误)等错误。用Clumsy模拟这个很容易。出现这些错误的原因是网络状况不佳。
所以,我解决这个问题的第一个想法是“再试一次”。当我收到此错误时,我只是再试一次然后它运行良好。像魔术一样。
这可能解决问题,但是,打开另一种问题。并非所有情况都适用于此解决方案。我会解释一下:
我将分为两种类型的场景:
我将重点关注数字2 。例如,假设我有:
“付费”存储过程是:
UPDATE tblUsers SET [Credits] -= @requestedCredits WHERE ID=@ID
调用SP是一个棘手的问题:
所以,“重试”策略不是一种选择。
我想通过为每一行添加“VersionID”来解决这个问题。我的SP现在:
UPDATE tblUsers SET [Credits] -= @requestedCredits, VersionId=NEWID() WHERE ID=@ID AND VersionID=@OldVersionId
在让用户Pay()之前,我会检查VersionID(随机GUID),如果在付款后网络故障后这个GUID没有改变,我会再试一次(证明数据没有改变) DB)。如果此VersionId已更改,则用户将获得该服务的付款。
问题是指我同时使用多台计算机时,这会使此解决方案出现问题。因为另一个实例可能对版本ID进行了Pay(),我认为我的更改是由我执行的(错误的)。
怎么办?
答案 0 :(得分:1)
听起来您正在从本地/内部部署/远程(即非Azure属性)到SQL Azure数据库进行SQL查询。
处理此问题的一些可能机制是
带有API的Azure托管数据访问层
考虑创建Azure WebApp或VM上托管的瘦数据访问层API,以便从远程计算机调用。此API服务可以可靠地与SQL Azure交互。
SQL比HTTP端点对超时和网络问题更敏感。特别是如果您的查询涉及大量数据的传输。
配置增加的超时
问题中未指定C#应用程序使用的数据库访问机制。许多用于数据访问的库或函数允许您为连接指定增加的超时。
虚拟专用网
Azure允许您创建具有更好网络连接的站点到站点或点到站VPN。但是,这是最不优选的机制。
答案 1 :(得分:1)
你永远不会盲目地重试。如果出现错误,您读取当前状态,然后重新应用逻辑,然后写入新状态。 “适用逻辑”的含义因案例而异。再次使用表单呈现用户,刷新网页,在业务逻辑中运行方法,任何事情。
它的要点是你永远不能简单地重试操作,而不是首先重新加载持久状态。唯一的事实是DB中的内容,错误是警告您的缓存状态是陈旧的。