【发布时间】:2018-11-19 15:21:48
【问题描述】:
当我在 SQL Server 2017 上运行 tSQLt 测试时收到以下错误,该测试设置在 Always On 可用性组中,该可用性组在 AG 组上配置了 DTC_SUPPORT = PER_DB。如果我关闭 DTC 支持,它工作正常。我们的环境需要 DTC。有没有办法在 tSQLt 中解决这个问题,或者是否有不同的方法来配置 SQL,以便 DTC 和 tSQLt 都可以工作?
这是错误:
Test Procedure: [xxx].[zzfnCipValidateCustomerAddress].[test '12345' Zip Codes] on DbServer
[zzfnCipValidateCustomerAddress].[test '12345' Zip Codes] failed: (Error) Cannot promote the transaction to a distributed transaction because there is an active save point in this transaction.[16,1]{zzfnCipValidateCustomerAddress.test '12345' Zip Codes,36} (There was also a ROLLBACK ERROR --> The current transaction cannot be committed and cannot be rolled back to a savepoint. Roll back the entire transaction.{tSQLt.Private_RunTest,160})
这是失败的测试之一:
CREATE PROCEDURE [zzfnCipValidateCustomerAddress].[test '12345' Zip Codes]
AS
BEGIN
--Assemble
/*
Test to determine if function is an Inline Table Valued function or not
since this function is being rewritten to be an ITVF function and this test should
pass both versions
*/
DECLARE @IsITVF BIT;
SELECT @IsITVF = IIF(fc.FunctionCount > 0, 1, 0)
FROM
(
SELECT COUNT(*) AS FunctionCount
FROM sys.sql_modules AS sm
JOIN sys.objects AS o
ON sm.object_id = o.object_id
WHERE sm.object_id = OBJECT_ID('dbo.fnCipValidateCustomerAddress')
AND o.type = 'IF' --'IF' = Inline Valued Table Function
) AS fc;
SELECT @IsITVF;
--DROP TABLE IF EXISTS zzfnCipValidateCustomerAddress.TestData;
CREATE TABLE zzfnCipValidateCustomerAddress.TestData
(
AddressLine1 VARCHAR(100),
AddressLine2 VARCHAR(100),
City VARCHAR(50),
StateAbbr VARCHAR(3),
ZipCode VARCHAR(9)
);
INSERT INTO zzfnCipValidateCustomerAddress.TestData
(
AddressLine1,
AddressLine2,
City,
StateAbbr,
ZipCode
)
VALUES
('Test', NULL, 'Test', 'AZ', '12345');
CREATE TABLE zzfnCipValidateCustomerAddress.Expected
(
AddressLine1 VARCHAR(100),
AddressLine2 VARCHAR(100),
City VARCHAR(50),
StateAbbr VARCHAR(3),
ZipCode VARCHAR(9),
CipExceptionReasonId INT
);
INSERT INTO zzfnCipValidateCustomerAddress.Expected
(
AddressLine1,
AddressLine2,
City,
StateAbbr,
ZipCode,
CipExceptionReasonId
)
VALUES
('Test', NULL, 'Test', 'AZ', '12345', 8);
--Act
IF (@IsITVF = 0)
BEGIN
SELECT td.AddressLine1,
td.AddressLine2,
td.City,
td.StateAbbr,
td.ZipCode,
dbo.fnCipValidateCustomerAddress(td.AddressLine1, td.AddressLine2, td.City, td.StateAbbr, td.ZipCode) AS CipExceptionReasonId
INTO zzfnCipValidateCustomerAddress.Actual
FROM zzfnCipValidateCustomerAddress.TestData AS td;
END;
ELSE
BEGIN
SELECT fcvcat.AddressLine1,
fcvcat.AddressLine2,
fcvcat.City,
fcvcat.StateAbbr,
fcvcat.ZipCode,
fcvcat.CipExceptionReasonId
INTO zzfnCipValidateCustomerAddress.Actual
FROM zzfnCipValidateCustomerAddress.TestData AS td
CROSS APPLY dbo.fnCipValidateCustomerAddress(
td.AddressLine1,
td.AddressLine2,
td.City,
td.StateAbbr,
td.ZipCode
) AS fcvcat;
END;
--Assert
EXEC tSQLt.AssertEqualsTable @Expected = N'zzfnCipValidateCustomerAddress.Expected',
@Actual = N'zzfnCipValidateCustomerAddress.Actual',
@Message = N'',
@FailMsg = N'Zip with value of ''12345'' did not generate a CipExceptionReasonId as expected';
END;
【问题讨论】:
-
我需要比这更多的信息才能开始故障排除。首先,失败的测试是什么样的。是否有一个特定的陈述失败了?测试是否涉及任何形式的事务管理? - 或者在那个环境中每个测试都失败了?
-
我添加了一个按要求失败的测试示例。我没有在测试中使用任何事务管理。此外,所有测试都失败了。被测试的函数是一个表值函数,也是一个表值函数并且不涉及任何事务管理。如果您需要任何其他信息,请告诉我。
-
所以,我不明白为什么您处于启用始终在线的环境中。测试(尤其是 tSQLt)永远不应该在生产环境中运行。你能告诉我更多关于你的设置吗?
-
@sebastian-meine 我们的 DBA 也将我们的开发环境用作他们的“开发”区域,因此他们首先将他们想要在生产环境中实现的所有功能设置到我们的开发环境中,然后再推广这些功能.这允许他们首先验证他们的 AlwaysOn 配置是否在 Dev 中工作,并且他们可以验证当他们在 UAT 和生产中实现它时它不会中断。他们对其他功能/配置也做同样的事情。我们的目标是使我们的每个环境之间的差异尽可能小。
-
如果您创建一个空测试(仅包含 RETURN 语句的测试),然后只执行该测试,您是否仍会收到相同的错误?
标签: sql-server alwayson tsqlt