为什么时态表会记录事务的开始时间?

Jam*_*son 9 transaction temporal-tables sql-server-2016

更新时态表中的一行时,该行的旧值存储在历史表中,事务开始时间为SysEndTime. 当前表中的新值将事务开始时间作为SysStartTime

SysStartTimeSysEndTime是时datetime2态表用于记录某行何时是当前版本的列。事务开始时间是包含更新的事务开始的时间。

BOL 说:

系统 datetime2 列中记录的时间基于事务本身的开始时间。例如,在单个事务中插入的所有行都将在对应于 SYSTEM_TIME 周期开始的列中记录相同的 UTC 时间。

示例:我开始更新 Orders 表中的所有行,20160707 11:00:00事务运行需要 5 分钟。这会在历史记录表中为每一行创建一行SysEndTimeas 20160707 11:00:00。当前表中的所有行都有一个SysStartTimeof 20160707 11:00:00

如果有人在20160707 11:01:00(更新正在运行时)执行查询,他们将看到旧值(假设默认读已提交隔离级别)。

但是,如果有人然后使用AS OF语法来查询时态表,因为20160707 11:01:00他们会看到新值,因为他们SysStartTime将是20160707 11:00:00.

对我来说,这意味着它不会像当时那样显示这些行。如果它使用事务结束时间,则问题将不存在。

问题:这是设计使然吗?我错过了什么吗?

我认为它使用事务开始时间的唯一原因是它是事务开始时唯一的“已知”。它不知道事务开始时何时结束,并且在结束时应用结束时间需要时间,这会使它应用的结束时间无效。这有意义吗?

应该允许您重新创建问题。

SQL*_*joe 3

这个想法是跟踪逻辑时间与物理时间。逻辑只是指用户/应用程序期望插入/更新/删除的时间。事实上,无论出于何种原因,DML 操作可能需要一段时间,这一事实没有意义,甚至不能被用户轻易确定和理解。如果您曾经不得不向会计师解释锁与闩锁争用(我曾经),那么这是一个类似的情况。

例如,当鲍勃“告诉”应用程序鲍勃所在部门的所有员工将开始赚取 42 美元/分钟时20160707 11:00:00,鲍勃(和他的员工)预计从那时起每个人的工资现在都按 42 美元/分钟计算。Bob 并不关心要实现此效果,应用程序必须对每个员工的数据库进行 2 次读取和 6 次写入,并且他们的数据 + 日志文件位于一堆 RAID-5 SATA II 驱动器上,因此需要大约 7 分钟为 Bob 的所有 256 名员工完成任务。鲍勃、他的会计师和薪资经理关心的是,他的所有员工的工资从 42 美元/分钟开始20160707 11:00:00。否则,在 更新记录的员工20160707 11:00:01会有点恼火,而在 更新记录的员工20160707 11:00:07将聚集在工资部门外。

有有效的用例来跟踪物理时间,例如调试和取证,但对于最终用户来说,它通常毫无意义。Tlog 保留每个写入操作的顺序和计时信息(以及其他信息),因此如果您知道如何查看,它就在那里。