For a long time I've been using the following structure when using TransactionScope.
using(var con = new SqlConnection(CONNECTIONSTRING))
{
con.Open();
foreach(var file in files)
{
try
{
using(var tran = new TransactionScope())
{
using(var cmd = new SqlCommand(CMDTEXT1, con)
{
//add parameters
//ExecuteScalar or ExecuteNonQuery
}
//...repeat above as needed for other inserts
//...run other C# methods like FTP upload
tran.Complete();
}
}
catch(Exception ex)
{
//log exception
}
}
}
Today, my FTP server was down but my SQL server was up. The error was properly caught and tran.Complete never ran. I would expect tran to rollback the changes but instead it had inserted all my commands.
Is this because the SqlConnection
is not within the TransactionScope
? Do I have to start a new SqlConnection
for each transaction? I want to retain this structure so I can reuse the SqlConnection
so I considered replacing new TransactionScope
with con.BeginTransaction
but I read that it doesn't allow the mixing of C# (I need to run C# methods like FTPUpload
). Did I misintrepret this?
Answered by comments
Is this because the SqlConnection
is not within the TransactionScope
? Yes
Do I have to start a new SqlConnection
for each transaction? Yes
Did I misintrepret this? I confused EntityFramework.BeginTransaction
with SqlConnection.BeginTransaction
.