sql-server - 如何批量更新具有大量活跃读者的 SQL Server 数据库

标签 sql-server database locking snapshot-isolation

我正在为以下场景设计 SQL Server 2012 数据库的解决方案

  • 数据库包含大约 100 万条记录,在 4 或 5 个表之间具有一些简单的父子关系
  • 数据库上有 24x7 的高读取负载
  • 我们每天收到一次包含大约 1000 个插入、更新和删除的批处理,这些应该合并到数据库中,有时这个数字可能更高。
  • 除了每日批处理之外,没有其他数据库写入者

有一些“特殊”要求

  1. 读者应该不会因为这些更新而遇到任何明显的延迟
  2. 从读者的角度来看,应该以原子方式处理整个批处理。读者不应看到部分处理的批处理
  3. 如果更新中途失败我们需要回滚该批处理的所有改动
  4. 批处理本身时间紧迫,通过简单的实现,现在只需几分钟就可以了。

我想到的方案是

  • 将单个数据库事务围绕整个更新批处理(这可能是一个大事务),并使用快照隔离让读者在更新运行时读取原始数据。

  • 使用分区切换,似乎这个功能是为这种用例设计的。缺点似乎是,在我们开始处理批处理之前,我们需要创建所有原始数据的副本。

  • 切换整个数据库。我们可以创建整个数据库的副本,处理该副本中的批处理,然后将所有客户端重定向到该数据库(例如,通过更改它们的连接字符串)。这甚至应该允许我们将数据库设为只读,甚至可能创建数据库的多个副本以实现可伸缩性。

哪些选项或其他选项最适合这种情况,为什么?

最佳答案

  1. 交易策略会阻塞并导致延迟。

分区切换并不能真正解决您的解决方案,因为您应该考虑与今天对数据库进行的操作相同......(因此回滚/插入)仍然会阻塞,但它可以被隔离只是部分数据而不是全部...

最好的办法是使用 2 个数据库并切换连接字符串...

或者使用 1 个数据库和 2 组表,并使用交换的 View 或存储过程来查看“事件”表。您仍然可能会遇到磁盘争用问题,但从锁定的角度来看,您会没事的。

关于sql-server - 如何批量更新具有大量活跃读者的 SQL Server 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24534089/

相关文章:

sql-server - 有没有办法在脚本中暂停或等待几分钟?

sql-server - 临时表是线程安全的吗?

java - 如何检查 double 是否为空?

windows - 如何在 TortoiseSVN 上查看锁定消息

java - wait() 如何在 Java 中取回锁

java - 多生产者和消费者多线程 Java 未按预期工作

sql-server - Windows Azure、 Entity Framework 。不支持关键字 : 'metadata' .

sql-server - Azure SQL 数据库中的 SQL Server Telegraf 插件需要哪些拨款

database - h2 删除约束失败后删除列

python - 从多个连接中选择特定的mysql连接