using System.Transactions; using FluentAssertions; using Microsoft.Data.SqlClient; using Xunit; namespace SIGCM2.Api.Tests.Audit; /// UDT-010 Batch 0 — anti-MSDTC spike. Validates design decision #D-1: /// TransactionScope with AsyncFlowEnabled must NOT escalate to MSDTC when /// multiple SqlConnections share a single connection string. If this fails, /// UDT-010 must pivot to explicit IUnitOfWork. [Collection("ApiIntegration")] public sealed class TransactionScopeSpikeTests { private const string ConnectionString = "Server=TECNICA3;Database=SIGCM2_Test;User Id=desarrollo;Password=desarrollo2026;TrustServerCertificate=True;"; [Fact] public async Task TransactionScope_DoesNotEscalateToMSDTC_WithSingleConnectionString() { var txOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }; using var tx = new TransactionScope( TransactionScopeOption.Required, txOptions, TransactionScopeAsyncFlowOption.Enabled); await using (var conn1 = new SqlConnection(ConnectionString)) { await conn1.OpenAsync(); using var cmd1 = conn1.CreateCommand(); cmd1.CommandText = "SELECT 1"; var result1 = await cmd1.ExecuteScalarAsync(); result1.Should().Be(1); } await using (var conn2 = new SqlConnection(ConnectionString)) { await conn2.OpenAsync(); using var cmd2 = conn2.CreateCommand(); cmd2.CommandText = "SELECT 1"; var result2 = await cmd2.ExecuteScalarAsync(); result2.Should().Be(1); } var current = Transaction.Current; current.Should().NotBeNull("TransactionScope must set an ambient transaction"); current!.TransactionInformation.DistributedIdentifier .Should().Be(Guid.Empty, "SQL Server with a single connection string must NOT escalate to MSDTC. " + "If this assertion fails, UDT-010 design must pivot to explicit IUnitOfWork " + "(see sdd/udt-010-auditoria-trazabilidad/design #D-1)."); tx.Complete(); } }