【问题标题】:Does T-SQL have a mechanism for reading rows as of beginning of transaction?T-SQL 是否具有在事务开始时读取行的机制?
【发布时间】:2020-06-13 16:20:25
【问题描述】:

我一直无法找到解决此问题的文档,并且我尝试了可序列化和快照隔离级别都没有任何好处。

我有兴趣在事务期间查询表,我在事务中修改了表,但我的查询不知道这些数据修改。

我确信我可以仔细排序并可能使用临时表来完成我的功能,但如果有查询提示或隔离级别可以简化我的代码,我想使用它!

【问题讨论】:

  • 如果您的意思是读取您已修改的行,因此它们被锁定以供其他事务使用,没有什么特别的事情可做,因为它们始终可用于您的事务。如果您打算在更新之前读取行的先前版本,那么您不能这样做,如果您需要这样做,请在您的 update 中添加一个 output into 子句并捕获您的 deleted.* 列对表变量感兴趣。
  • 我的意思是后者...感谢您在子句中指出该输出,它可能对我想要完成的目标大有帮助!
  • 另外@GSerg,如果输出子句是我能得到的最接近我的问题,你应该把它作为一个答案,这样我就可以接受它。
  • 您可以使用 2 个不同的连接来执行此操作,第一个启动事务处于快照隔离级别,另一个执行修改。在第一个连接上执行的查询将返回快照事务开始时存在的数据。
  • 确实如此,但我需要在进行更改的事务中访问旧数据,所以我认为在这种情况下使用 2 个连接不会起作用。

标签: sql-server tsql transactions isolation-level


【解决方案1】:

在常规表中,您无权访问您在当前事务中修改的行的先前版本。

如果表确实是正则表,你可以add the output clause到你的update语句捕获之前的版本:

declare @t table(...);

update ...
set ...
output deleted.column1, ... into @t;

如果表是通过时态表,你can访问以前的版本:

declare @before_update datetime = getdate();

update ... ;

select ... from table ... for system_time as of @before_update;

请注意,鉴于 SQL Server 的并发特性,这可能不是您想要的。如果另一笔交易介于您的= getdate()update 之间,它可能会返回有点太旧的数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多