gpt4 book ai didi

.net - 嵌套 TransactionScope 和/或嵌套连接导致 MSDTC 升级

转载 作者:行者123 更新时间:2023-12-02 07:07:51 24 4
gpt4 key购买 nike

我正在尝试避免我的应用程序中的 MSDTC 升级。我将 LINQ 与 SQL Server Express 2008 R2 一起使用,稍后将使用完整版本。

我编写了一个数据库包装类,它根据需要创建连接并尽快处理它们。连接字符串在所有连接中保持相同。

这是我的类(class)的一个非常精简的版本:

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,并且可能存在 TransactionScope 的嵌套和/或对 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 且不引入锁的情况下良好运行?

谢谢

最佳答案

您是否在事务范围内仅使用一个与数据库的连接?在事务范围内使用相同或不同的连接字符串创建两个连接会将事务升级为分布式事务。

您可以将连接存储在线程静态变量中,并在事务中的所有工作完成后关闭/处置它。然后每个线程都会有它自己的连接。

当您向逻辑添加锁时,您可能不会获得分布式事务,因为连接池每次都会返回相同的连接。

关于.net - 嵌套 TransactionScope 和/或嵌套连接导致 MSDTC 升级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9684883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com