We track the same information across two databases in tables that have a similar (enough) schema. When we update the data in one database we want to make sure the data stays in sync with the table in the other database.
We use Entity Framework 5 in both databases, so I had originally wanted to simply import a DbContext
of the secondary database and use TransactionsScope
to make sure the Create/Updates were atomic.
However, I quickly found out that would be a pain to code, since the table names are the same (anyone working in this controller would have to refer to the Product
table as <Conext>.Product
), so I used a SqlConnection
object for the secondary table, but received some results I don't quite undestand.
If I use the syntax below, the two tables will update atomically/everything goes as planned.
var scopeOptions = new TransactionOptions();
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
scopeOptions.Timeout = TimeSpan.MaxValue;
var sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["Monet"].ConnectionString);
sqlConn.Open();
SqlCommand sqlCommand = sqlConn.CreateCommand();
sqlCommand.CommandText = InsertMonetProduct(product);
using (var ts = new TransactionScope(TransactionScopeOption.Required, scopeOptions))
{
db.Product.Add(product);
db.SaveChanges();
sqlCommand.ExecuteNonQuery();
ts.Complete();
}
However if I use this syntax below the code crashes on the db.SaveChanges()
command with the following message:
Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.
var scopeOptions = new TransactionOptions();
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
scopeOptions.Timeout = TimeSpan.MaxValue;
using (var ts = new TransactionScope(TransactionScopeOption.Required, scopeOptions))
{
using(var sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["Monet"].ConnectionString))
{
sqlConn.Open();
using (SqlCommand sqlCommand = sqlConn.CreateCommand())
{
sqlCommand.CommandText = InsertMonetProduct(product);
sqlCommand.ExecuteNonQuery();
db.Product.Add(product);
db.SaveChanges();
}
ts.Complete();
}
}
Any idea why the first syntax works and the second crashes? From what I've read online this is supposed to be a change made on the database/database server itself.