考虑以下:
CREATE PROCEDURE dbo.usp_trantest AS
SELECT @@TRANCOUNT as trancount;
GO
当我usp_trantest
从 SSMS 中手动调用时,转数为 0。如果我运行包含查询相同存储过程的数据集的 SSRS 报告,则转数记录为 1。
对 SSRS 方法进行 T-SQL 跟踪会显示存储过程调用的跟踪事件,这与我在 SSMS 中所做的相同。
是否有一些行为可能会根据 SSRS 上下文而改变?比如,为动态 sql 调用或其他东西打开一个隐式事务,或者 SSRS 在 T-SQL 之外创建一个事务上下文?
编辑:
在某人现在已删除的答案中(谢谢,陌生人!)有人建议 SSRS 报告的数据集可能已选中“处理查询时使用单个事务”。确实是这样!
我做了一些进一步的测试,并且在未选中此设置的@@TRANCOUNT
情况下,无论是在 SSMS 中运行还是从 SSRS 报告中运行,都是相同的。
因此,我们似乎可以得出结论,此数据源设置确实会导致 SSRS 报告在运行查询之前在数据库上创建事务上下文。由于这个额外的事务没有出现在 T-SQL 跟踪中,我们可以假设它是使用 API 方法打开的,而不是 T-SQL 语句。
在 SSRS 报告的数据源上,有一个“处理查询时使用单个事务”的属性。标记此复选框有几种不同的行为:
1) 如您所见,如果选中此复选框,SSRS 将使用显式事务处理使用此数据源的数据集。未标记时,没有显式事务。
2) 如果未选中此复选框,则使用数据源的数据集将并行执行,使用与服务器的单独连接。如果勾选了复选框,则数据集使用单个连接并按顺序处理。
此外,使用此复选框可能有不同的动机。主要的两个是:
1)读取一致性:如果您使用Snapshot Isolation,您可能希望所有数据集与单个时间点保持一致。在这种情况下,使用单个显式事务并使用 Snapshot 隔离级别可以确保事务中的所有语句与单个时间点保持一致。
2)性能:取决于许多因素(这实际上是一个单独的主题),您可能会看到并行运行不同数据集的查询与串行运行它们之间的巨大性能差异。
在 SSRS 2012 中,我没有遇到此处所示的相同行为。尽管没有选中该框,但我的 SP 仍在交易中运行。
选中该框对交易计数没有影响。在这两种情况下,@@TRANCOUNT 都是 = 1。