Skip to content

Instantly share code, notes, and snippets.

@emanuelefirmani
Created April 15, 2020 23:00
Show Gist options
  • Save emanuelefirmani/0c1bb8fd071a8e18c421316cea2eeca2 to your computer and use it in GitHub Desktop.
Save emanuelefirmani/0c1bb8fd071a8e18c421316cea2eeca2 to your computer and use it in GitHub Desktop.
/// <summary>
/// This test verifies that UoW commits changes in a transaction.
/// Test is carried on by:
/// - running a transaction with exclusive lock on table LastUpdatingLog with the base.SqlConnection
/// - running the sut.Update (which opens another write transaction)
/// - execute SELECTs using another connection (with NoLock for checking uncommitted values)
/// The sut can commit its transaction only after first transaction is committed
/// </summary>
[Fact]
public void should_save_in_transaction()
{
var builder = new ContainerBuilder();
builder.RegisterModule<IocUoWTestModule>();
var container = builder.Build();
using var lf = container.BeginLifetimeScope();
var sut = lf.Resolve<Updater>();
SqlConnection.Open();
using var transaction = SqlConnection.BeginTransaction();
SqlConnection.Execute("SELECT 1 FROM LastUpdatingLog WITH (TABLOCKX)", transaction: transaction); // creates an exclusive lock on table LastUpdatingLog
SqlConnection.Execute("INSERT INTO LastUpdatingLog (Id) VALUES(17)", transaction: transaction);
//sut is run asynchronously, so that tests can be run before transactions are committed
var t = new Task(() => sut.Update("foo", 42));
t.Start();
using var tmpConn = new SqlConnection(LocalDbConnectionString.DbConnectionString);
//First transaction inserted the initial value, but uncommitted
var logIdNoLock = tmpConn.Query<int>("SELECT Id FROM LastUpdatingLog(NoLock)").Single();
logIdNoLock.Should().Be(17);
//No values are committed
var logId = tmpConn.Query<int?>("SELECT Id FROM LastUpdatingLog").SingleOrDefault();
logId.Should().BeNull();
//sut still has not committed the customer
var customer = tmpConn.Query<MacCustomer>("SELECT * FROM Customer").SingleOrDefault();
customer.Should().BeNull();
//Commit transaction with exclusive lock, then waits for the sut to complete the task
transaction.Commit();
t.Wait();
//Final values are those inserted by sut
logId = tmpConn.Query<int>("SELECT Id FROM LastUpdatingLog").SingleOrDefault();
logId.Should().Be(42);
customer = tmpConn.Query<MacCustomer>("SELECT * FROM Customer").Single();
customer.Number.Should().Be("foo");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment