0

在我们的应用程序开发过程中,我们引入了 Azure SQL 地理复制,以改善不同地理位置的用户体验和响应能力。

目前在测试中,我们有两个实例 - 一个主要和次要*,其中一个在美国,另一个在欧洲。

问题

即使调用了 sp_wait_for_database_copy_sync,主数据库中新更新的数据似乎在辅助数据库中也不可用,这应该可以确保这一点

重现问题的步骤

  1. 用户连接到辅助实例
  2. 用户对数据进行更新(进入数据库的“更新”或“插入”)
  3. 事务已提交
  4. 使用适当的参数调用sp_wait_for_database_copy_sync过程,以确保在更新调用解除阻塞时数据已复制到辅助实例中
  5. 一旦更新调用解除阻塞,就会在辅助数据库上尝试提取数据(包括新更新或插入的数据) 。
  6. 新更新或插入的数据不包含在结果集中 - 尽管数据库复制同步过程不能确保数据将在更新调用解除阻塞时复制

技术实现细节

当一个实体即将更新、事务提交和数据同步保证时,依次调用以下三行代码:

  1. ISession.Save(object obj)用于保存新实体
  2. ISession.Flush()用于提交事务
  3. ISession.CreateSQLQuery("EXEC sys.sp_wait_for_database_copy_sync @target_server = N\'secondary-server\', @target_database = N\'database\';").ExecuteUpdate()用于执行调用阻塞同步过程

问题

以上三行代码可能有什么问题?我看到的可能罪魁祸首是:

  1. ISession.Flush不同步执行,因此在执行阻塞存储过程时,事务尚未实际提交
  2. ISession.CreateSQLQuery("EXEC sys.sp_wait_for_database_copy_sync @target_server = N\'secondary-server\', @target_database = N\'database\';").ExecuteUpdate()实际上并没有被阻止。

任何有关如何解决上述两个问题或您看到的其他问题的想法将不胜感激。

  • 在这种情况下,主要和次要与异地复制设置有关。
4

4 回答 4

0

Azure SQL DB 异地复制是为用户数据库设计的,而不是为主数据库设计的。将更新文档以明确这一点。

于 2017-06-22T15:31:18.230 回答
0

当您在这里说“主”时,您指的是异地复制关系中的主数据库,还是逻辑主数据库?

于 2017-06-22T17:00:52.357 回答
0

NHibernate 是同步的。ISession.Flush总是同步的。但是,如果您处于分布式TransactionScope(检查System.Transactions.Transaction.Current?.TransactionInformation?.DistributedIdentifier ?? default(Guid) != Guid.Empty)中,则 MSDTC 会启动并导致数据库中的实际提交是异步的,最终发生在范围处置之后。在这里阅读更多。.

我不确定 Azure 是否接受分布式事务,因此这可能不是您遇到问题的原因。

如果您处于分布式事务的情况下,那么根据您的查询/数据库设置/...引起的锁,您将可以从数据库中读回您提交的数据,依靠事务锁来阻止您,直到它实际提交,然后执行同步。或者,如果您没有被锁定,请轮询数据库直到看到您的数据(当然,这对于性能来说甚至是最差的),然后执行您的同步。

顺便说一句,我不知道 Azure 异地复制是如何工作的,但如果它也使用 MSDTC,那么它本身可能会出现这些异步问题。

关于 SQLExec实际上没有被阻止,那将是一个 SQL Azure 问题。

于 2017-07-10T15:35:22.173 回答
0

我忘记在这里发帖了,但问题是以下过程虽然阻塞,但实际上并不能保证一旦解除阻塞的数据在所有实例中都可用:sp_wait_for_database_copy_sync。

于 2019-01-05T00:20:43.993 回答