gpt4 book ai didi

transactions - 多次使用 TransactionScope

转载 作者:行者123 更新时间:2023-12-04 06:12:56 25 4
gpt4 key购买 nike

这是使用事务范围的正确方法吗:

我有一个代表事物的一部分的对象:

public class ThingPart
{
private DbProviderFactory connectionFactory;

public void SavePart()
{
using (TransactionScope ts = new TransactionScope()
{
///save the bits I want to be done in a single transaction
SavePartA();
SavePartB();
ts.Complete();
}
}

private void SavePartA()
{
using (Connection con = connectionFactory.CreateConnection()
{
con.Open();
Command command = con.CreateCommand();
...
command.ExecuteNonQuery();
}
}

private void SavePartB()
{
using (Connection con = connectionFactory.CreateConnection()
{
con.Open();
Command command = con.CreateCommand();
...
command.ExecuteNonQuery();
}
}
}

以及代表事物的东西:
public class Thing
{
private DbProviderFactory connectionFactory;

public void SaveThing()
{
using (TransactionScope ts = new TransactionScope()
{
///save the bits I want to be done in a single transaction
SaveHeader();
foreach (ThingPart part in parts)
{
part.SavePart();
}
ts.Complete();
}
}

private void SaveHeader()
{
using (Connection con = connectionFactory.CreateConnection()
{
con.Open();
Command command = con.CreateCommand();
...
command.ExecuteNonQuery();
}
}
}

我也有管理很多事情的东西
public class ThingManager
{
public void SaveThings
{
using (TransactionScope ts = new TransactionScope)
{
foreach (Thing thing in things)
{
thing.SaveThing();
}
}
}
}

我的理解是:
  • 连接不会是新的,每次都会从池中重用(假设 DbProvider 支持连接池并且已启用)
  • 如果我只是调用 ThingPart.SavePart,交易将是这样的。 (从任何其他类的上下文之外)然后部分 A 和 B 要么都被保存,要么都不会。
  • 如果我打电话Thing.Save (来自任何其他类的上下文之外)然后 Header 和所有部分将全部保存或不保存,即一切都将发生在同一个事务中
  • 如果我打电话ThingManager.SaveThings那么我所有的东西都会被保存,或者什么都不会保存,即一切都将发生在同一个事务中。
  • 如果我更改 DbProviderFactory使用的实现,应该没有区别

  • 我的假设正确吗?

    忽略任何关于对象结构或持久性责任的事情,这是一个帮助我理解我应该如何做事的例子。部分原因是当我尝试用 SqlLite 作为数据库提供程序工厂替换 oracle 时它似乎不起作用,我想知道我应该花时间调查哪里。

    最佳答案

    回答您的问题(我假设使用 Microsoft SQL Server 2005 或更高版本):

  • Connections will not be new and reused from the pool


  • 这取决于 - 例如如果所有连接都指向同一个数据库,使用相同的凭据,并且 SQL 能够使用轻量级事务管理器(SQL 2005 及更高版本),则 SAME 连接将在聚合事务中的后续步骤中重复使用。 (但如果这是您的要求,SQL 连接池仍然有效?)
  • Atomic SavePart - 是的,这将按预期工作 ACID。
  • 是的,嵌套具有相同作用域的 TransactionScopes 也将是原子的。事务只会在最外面的 TS 完成时提交。
  • 是的,也是原子的,但请注意,您将升级 SQL 锁。如果单独提交每个事物(及其 ThingParts)是有意义的,那么从 SQL 并发的角度来看,这将是更可取的。
  • Provider 将需要作为 TransactionScope 资源管理器兼容(可能也符合 DTC)。例如不要将您的数据库移动到 Rocket U2 并期望 TransactionScopes 能够工作。

  • 只有一个问题- new TransactionScope() defaults to isolation level READ_SERIALIZABLE - 对于大多数情况,这通常过于悲观 - READ COMMITTED 通常更适用。

    关于transactions - 多次使用 TransactionScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7553971/

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