通过对象隔离实现原子性

Atomicity through object segregation

提问人:Chaos 提问时间:10/31/2023 最后编辑:Chaos 更新时间:10/31/2023 访问量:32

问:

我面临着一个我不知道如何有效解决的问题,该问题涉及大量使用DBMS。我有一个长时间运行的过程刷新(通过批量插入/删除/更新)许多表。这些表由后端从数据库读取数据来访问;拥有干净的信息是必不可少的;读取过时的数据不是问题,重要的是避免读取部分更新的信息。

我正在尝试实现某种发布机制,其目的是保证原子性并避免读取部分重新计算的数据(可能会更改或消失)。我需要保证后端通过此重新计算过程以原子方式读取数据。

我正在考虑复制内存中对象隔离的经典解决方案,该解决方案基本上将两个不同的内存区域中的新旧对象分开,让它们成为 A 和 B。所有读操作都在 A 上执行,写操作在 B 上执行;该过程完成后,两个区域的角色将互换。因此,读取始终由过时或刷新的数据支持,并且永远不会读取中间结果。

我认为我应该采用这种策略,因为当过程更新数据库时,由于事务之间的高度偶然性,来自后端的事务往往会超时。我认为物理分离数据也会改善这方面。我还怀疑这不是描述我想采用的策略的恰当词,但在垃圾收集器的上下文中,这个问题通常以这种方式解决和命名。segregation

显而易见的解决方案是复制所有表并选择表的工作版本来执行查询,可能在存储过程中执行查询。然而,这种解决方案存在将所有查询重写为存储过程并使用游标的问题......另一个问题出现在后端,由于我必须编写大量的本机查询,我使用的技术 (JPA) 非常不灵活。

问题是:有没有一种方便的方法可以通过 SQL Server 的功能来实现这种发布机制?

sql-server jpa 存储过程 原子

评论


答:

3赞 SQLpro 10/31/2023 #1

只需使用命令激活数据库中的乐观锁定

ALTER DATABASE CURRENT SET READ_COMMITTED_SNAPSHOT ON;

一旦您的事务处理所有数据完成,新数据将向用户公开。在处理过程中,您的用户将能够读取旧数据。

无需通过创建天然气工厂来重新发明轮子!!!

评论

0赞 Chaos 10/31/2023
我不知道这面旗帜的存在。我打开了它,开始测试数据库和后端的联合行为。
0赞 Lajos Arpad 10/31/2023
测试@Chaos成功?
0赞 Chaos 10/31/2023
绝对!使用这个标志,我利用了一个我不知道的复杂数据库功能。
0赞 SQLpro 10/31/2023
当心一件事......所有交易都将使用乐观锁定而不是悲观锁定。如果对应用程序中的某些其他代码使用显式事务,则进程的行为将不完全相同。特别是,READ COMMITTED 始终转换为 REPEATABLE READ。另一个需要调查的特点是 tempdb 存储,它会增加,因为它存储了快照事务中使用的数据版本(由乐观锁定产生)。
0赞 Chaos 11/2/2023
谢谢你的建议,我会把它添加到待办事项列表中。幸运的是,我没有在其他地方使用显式交易。