我試圖避免MSDTC在我的應用程序中升級。我在SQL Server Express 2008 R2中使用LINQ,稍後將使用完整版本。導致MSDTC升級的嵌套TransactionScope和/或嵌套連接
我寫了一個數據庫包裝類,它根據需要創建連接並儘快處理它們。連接字符串在所有連接中保持不變。
這裏是我班的一個非常精簡版:
public class SqlServerDatabaseWrapper {
public SqlServerDatabaseWrapper(string connectionString) {
ConnectionString = connectionString;
}
public string ConnectionString { get; private set; }
private static IDbConnection GetOpenConnection() {
var conn = new SqlConnection(ConnectionString);
conn.Open();
return conn;
}
// there is also a second method to return a value
// there is PerformCommandAction for SqlCommand as well
public void PerformDataContextAction<TContext>(Func<IDbConnection, TContext> creator, Action<TContext> action) where TContext : DataContext {
PerformConnectionAction(conn => {
using (var context = creator(conn))
action(context);
});
}
// there is also a second method to return a value
public void PerformConnectionAction(Action<IDbConnection> action) {
using (IDbConnection conn = GetOpenConnection(ConnectionString)) {
action(conn);
}
}
}
使用方法如下:
var db = new SqlServerDatabaseWrapper(connectionString);
db.PerformDataContextAction(
conn => new SomeDataContext(conn),
context => { /* do something */ }
);
如果我把周圍的PerformConnectionAction方法的內容鎖定,所以只有一個可以一次運行,然後一切正常,但有明顯的性能損失。但是,當我刪除它時,它會升級。
使用包裝器的代碼使用的是TransactionScope,並且可以嵌套TransactionScopes和/或調用PerformDataContextAction或PerformConnectionAction(每個都使用相同的連接字符串創建新的連接);在僞代碼(因爲這可能會在不同的類/方法發生):
var db = new SqlServerDatabaseWrapper(connectionString)
using (TransactionScope tran = new TransactionScope()) {
db.PerformDataContextAction(
/* ... */,
context => {
using (TransactionScope tran2 = new TransactionScope()) {
db.PerformConnectionAction(conn => { /* some stuff */ });
tran2.Complete();
}
}
tran.Complete();
}
還要注意有使用的可能發生在不同的點靜態成員的方法。
我還要補充一點,連接字符串如下:
Data Source=.\SQLEXPRESS;Initial Catalog=db1;User Id=test1;Password=test1;MultipleActiveResultSets=true;Enlist=false;
的問題是,我該如何重構/重寫我的代碼,使我的應用程序可以執行良好,沒有MSDTC,並沒有引入鎖?
感謝
您使用的是哪個版本的SQL Server? – Oded 2012-03-13 13:29:02
SQL Express 2008 R2,稍後將被放到完整版本 – enashnash 2012-03-13 13:30:43
我有點困惑,添加一個鎖可以防止升級,因爲'TransactionScope'是線程綁定的,鎖只會影響線程的相互作用,但不會影響訂單線程內的操作,除非你的線程引入了非確定性行爲,我可以看到鎖是如何改變的。如果您仍然對答案感興趣,請讓我們更多地瞭解線程方面的情況。 – 2013-10-11 09:16:37