繁体   English   中英

与Azure SQL数据库的可靠连接

[英]Reliable connection with Azure SQL Database

我开发了一个在Azure SQL数据库中存储数据的C#应用​​程序。

您可能知道,Azure SQL数据库位于Internet上的某个位置。 不是通过LAN网络(但这个问题也与LAN等可靠网络相关)。

我已经注意到,我不时会收到“连接已关闭”(或其他网络错误)等错误。 Clumsy模拟这个很容易。 出现这些错误的原因是网络状况不佳。

所以,我解决这个问题的第一个想法是“再试一次”。 当我收到此错误时,我只是再试一次然后它运行良好。 像魔术一样。

这可能解决问题,但是, 打开另一种问题 并非所有情况都适用于此解决方案。 我会解释一下:

我将分为两种类型的场景:

  1. 重试不能造成任何损害 - 像SELECT或DELETE这样的操作。 重试将具有相同的预期结果。 所以,有了这类问题 - 我的解决方案工作正常!
  2. 插入或更新 - 重试会损坏信息。

我将重点关注第2点。 例如,假设我有:

  • 用户表。 此表中的列:ID,UserName,Credits。
  • 存储过程使用户(按用户ID)支付部分学分。

“支付”存储过程是:

UPDATE tblUsers SET [Credits] -= @requestedCredits WHERE ID=@ID

调用SP是一个棘手的问题:

  • 如果这没有问题 - 我们没事。
  • 如果失败,我们不知道操作是否在DB上完成。 在此重试可能会导致用户支付两次费用

所以,这里的“重试”策略不是一种选择。

我想到的解决方案:

我想通过为每一行添加“VersionID”来解决这个问题。 我的SP现在:

UPDATE tblUsers SET [Credits] -= @requestedCredits, VersionId=NEWID() WHERE ID=@ID AND VersionID=@OldVersionId

在使用户Pay()之前,我将检查VersionID(随机GUID),如果在付款后网络故障后此GUID没有更改,我将再试一次(证明数据没有在数据库上更改) 。 如果此VersionId已更改,则用户将获得该服务的付款。

问题是当我同时使用多台机器时,这使得该解决方案成为问题。 因为另一个实例可能在版本ID上做了一个Pay(),我会认为我的更改是由我执行的(哪个错误)。

该怎么办?

听起来您正在从本地/内部部署/远程(即非Azure属性)到SQL Azure数据库进行SQL查询。

解决这个问题的一些可能机制是

  • Azure使用API​​托管数据访问层

    考虑创建托管在Azure WebApp或VM上的瘦数据访问层API,以便从远程计算机调用。 此API服务可以可靠地与SQL Azure交互。

    与HTTP端点相比,SQL对超时和网络问题更敏感。 特别是如果您的查询涉及大量数据的传输。

  • 配置增加的超时

    问题中未指定C#应用程序使用的数据库访问机制。 许多用于数据访问的库或函数允许您指定增加的连接超时。

  • 虚拟专用网

    Azure允许您创建具有更好网络连接的站点到站点或点对站VPN。 但是,这是最不优选的机制。

你永远不会盲目地重试。 如果出现错误,则读取当前状态,然后重新应用逻辑,然后写入新状态。 “适用逻辑”的含义因案例而异。 再次使用表单呈现用户,刷新网页,在业务逻辑中运行方法,任何事情。

它的要点是,你永远不能简单地重试操作,而不是首先重新加载持久状态。 唯一的事实是DB中的内容,错误是警告您的缓存状态是陈旧的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM