gpt4 book ai didi

c# - 使用 block 在现有 SqlConnection 中创建具有新 SqlConnection 的事务范围

转载 作者:行者123 更新时间:2023-11-30 13:58:28 27 4
gpt4 key购买 nike

我想执行一个 SELECT 查询,然后执行一系列 UPDATE 查询(都在同一个表上); UPDATE 在重复调用的单独方法中实现。如果其中一个 UPDATE 查询失败,我希望它们全部失败/回滚 - 所以我想在事务中登记它们。但是,我不确定应该在哪里打开 SqlConnection 以避免出现任何问题。我当前的实现如下所示:

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

// execute a single SELECT here

using (TransactionScope scope = new TransactionScope())
{
for (int i=0; i<...; i++)
{
Update(); // UPDATE query
}

scope.Complete();
}
}


Update()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

// execute a single UPDATE here
}
}

这是否应该在所有情况下都按预期工作?

是否可以在 SELECT 之前打开一个连接,然后在 Update() 方法中打开一个新连接?由于连接池,相同的连接将用于 SELECT 和 UPDATE 查询(connectionString 是相同的),但只有 UPDATE 查询才会被纳入事务,对吗?但是,如果在 Update() 中使用不同的连接会怎样?所有 UPDATE 查询是否仍会按预期在事务中登记并自动执行?

如果我理解正确,在关闭第一个连接后(在执行 SELECT 的 using block 之后)创建事务范围仍然有效,但会降低性能,因为连接将被关闭并且需要重新开放,对吗?或者实际上是为事务范围创建了一个新连接,并在每次调用 Update() 时打开和关闭?

最佳答案

Due to connection pooling, the same connection will be used for both SELECT and UPDATE queries

不,不会;它只有在您首先释放将连接放回池中时才能做到这一点——目前您同时有两个连接,所以这不可能是同一件事。您需要稍微调整一下:

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

// execute a single SELECT here
} // <==== end the first connection

using (TransactionScope scope = new TransactionScope())
{
for (int i=0; i<...; i++)
{
Update(); // UPDATE query
}

scope.Complete();
}

creating a transaction scope after closing the first connection (...) but would reduce performance, because connection would be closed and needed to be re-opened, correct

没有;当您“关闭”它时,实际上只是将它释放回池中;它不会关闭底层连接(除非您禁用了池)。关闭(或至少,处置)是正常的和预期的。

but only UPDATE queries will be enlisted in the transaction, right?

正确,因为那只是在事务范围内打开连接的地方

But what happens if different connection gets used in Update()? Will all UPDATE queries still enlist in a transaction as expected and execute atomically?

任何支持登记的连接(假设它在连接字符串中没有被禁用)都将被登记。但是,根据服务器的不同,这可能会使用 LTM 或可能会使用 DTC。如果您想确定您的连接:控制它们:

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

// execute a single SELECT here
} // <==== end the first connection

using (TransactionScope scope = new TransactionScope())
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
for (int i=0; i<...; i++)
{
Update(connection); // UPDATE query
}

scope.Complete();
}

请注意,我将 connection 传递给上面的 Update;这里 很明显 将使用单个连接(假设 Update 正常工作)。

关于c# - 使用 block 在现有 SqlConnection 中创建具有新 SqlConnection 的事务范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16855046/

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