事务范围(TransactionScope)是否支持原子数据库执行?

3

我目前正在开发一个项目,其中DAL使用ADO Entity Framework在.Net中实现。

数据库结构并不直观,我希望能够确保一些数据库操作是原子的。

我知道可以通过创建一个 STORED PROCEDURE 并使用 DB TRANSACTION(如在此SO文章中提到的)来实现。 (我正在使用SQL Server)

问题是,我希望尽可能地将逻辑保留在软件端,并考虑使用 .Net TransactionScope。 尽管我理解从软件角度来看它工作得很好(在整个范围未提交之前不会向数据库提交任何内容),但我怀疑它是否仍然确保了DB原子执行。

有人知道这方面的信息吗?

更具体地说,通常代码看起来像这样:

using (TransactionScope scope = new TransactionScope())
{
  /*
   * Do some opreations such as reads, write, insert, deletes
   */
   scope.Commit()
}

我希望确保括号内的所有内容都是“原子性”的(我猜想是隔离=SERIALIZABLE)。我的意思是,在代码范围内执行时,不希望数据库状态能够改变。


在ACID关系数据库中,“原子”单元是事务。选择正确的隔离级别进行任务并适当提交/回滚-但这对于数据外的关键区域没有帮助,因为它严格与RDBMS事务相关!使用TransactionScope是一种通过隐式线程本地事务来帮助处理此类事务的方法(可以节省传递参数的麻烦)。 - user166390
1
https://dev59.com/qXE85IYBdhLWcg3wNwx3#2886326 - Mitch Wheat
@Mitch:谢谢。您认为ADO实体框架完成的任何工作也是如此吗? - SRKX
@SRKX:没有进行检查,我不能100%确定。根据所执行的操作,实体框架可能会更改默认隔离级别。 - Mitch Wheat
我刚刚更新了我的答案,并添加了Entity Framework的细节。 - Richard Blewett
3个回答

2

TransactionScope运行在一个事务中(根据您的事务隔离级别,可能还包括读取操作)。

数据库提供者已经成为此事务的一部分,因为它们在事务范围内使用 - 因此,事务范围实际上是一个数据库事务(如果您有多个数据库/消息队列等参与事务,则可能更多)。

编辑:Entity Framework详细信息

Entity Framework使用基础提供程序的连接BeginTransaction方法。对于SqlConnection,它使用SqlServer的默认设置,因此将使用ReadCommitted。

因此,如果您不使用事务范围,则默认为Read Committed而不是Serializable。


你的意见是,在 TransactionScope 中应该包含什么?你认为模型的实例应该在作用域内创建,还是只有 SaveChanges() 方法很重要? - SRKX
在TransactionScope内创建模型(我假设您指的是ObjectContext包装器)。 - Richard Blewett

1
你知道“DB原子执行”是什么意思吗?有各种事务隔离级别。
当与SQL Server通信时,.NET的TransactionScope会注册一个SQL Server事务,默认情况下将使用Serializable隔离级别。

1
TransactionScope 默认使用 Serializable。 - Richard Blewett
1
你说得对,SQL Server 默认使用 READ COMMITTED 进行事务处理 - 不确定为什么他们在 TxScope 中选择了不同的方式 - 可能是为了让那些不习惯事务处理的人感到最少的惊讶。 - Richard Blewett
今天我学到了一些东西!TransactionScope并不像你期望的那样工作! - Mitch Wheat
所以基本上,默认情况下,从创建TransactionScope到调用Commit()的所有操作都将被数据库视为单个操作,包括(可能的)表读取、数据处理等? - SRKX
@SRKK:是的,只要连接在事务中注册了。 - Mitch Wheat

1

事务始终是原子性的,无论是在SQL中启动还是在客户端(例如TransactionScope)中启动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接