1

我正在开发一个 .NET Core web api 服务并在 BL 中有以下方法:

public async Task<SetParams> GetParams(CreateRequest request)
        {
            var user = await _userRepository.GetUserByLogin(request.Login);  
            var client = await _clientRepository.GetClientByCode( request.ClientCode);

            // many other getters here 

            return new SetParams
            {
                IdUser = user.IdUser,
                ClientName = client.Name,
                // and so forth...
            };
        }

我需要让所有实体都处于“脏读”模式。

所以,我试图以这种方式使用 TransactionScope:

public async Task<SetParams> GetParams(CreateRequest request)
        {
            using (var ts = new TransactionScope(
                TransactionScopeOption.Required,
                new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                var user = await _userRepository.GetUserByLogin(request.Login);
                var client = await _clientRepository.GetClientByCode(request.ClientCode);

                // many other getters here 

                ts.Complete();

                return new SetParams
                {
                    IdUser = user.IdUser,
                    ClientName = client.Name,
                    // and so forth...
                };
            }
        }

但是:1)这已经读取提交模式(我从这篇文章中知道我必须开始一个事务,但我这里没有会话或数据库上下文,因为我在 BL 中而不是在 DAL 中)

和 2) 以异常结束A TransactionScope 必须在创建它的同一线程上处理。

4

1 回答 1

1

您需要 Transaction 用于读取查询集(脏读)

我假设您具有高并发性来读取未提交的数据。这可能是在 Select 查询中使用事务的唯一用例。我认为它们仍然与少数 DML 操作交织在一起

从哪里开始 Transaction,BL / DAL,它需要 DbContext 吗?

这取决于您的用例,如果您的设计是从 BL 分派应作为事务一部分的多个业务查询,那么它是一个有效的起点,尤其是使用环境事务 (TransactionScope)。显式SessionorContext启动事务是其中一种机制,因为所有共享查询都无缝地登记在同一个事务上下文中,但是使用TransactionScopeor可以实现类似的事情CommittableTransaction,您可以利用TransactionScopeOption它来确保各种查询的参与:

  1. 使用Requires New启动 BL 和 DAL 级别的环境事务,使用Required确保相同的事务上下文用于登记。数据库连接应在可用范围内自动登记。
  2. 使用CommittableTransactionBL 中创建的相同对象被传递到 DAL 存储库,并且连接对象被显式登记
  3. 如果您的要求更具体一些,在此之前 No Commit 是可行的,直到完成单独线程上的所有子操作,然后查看DependantTransaction,它也是 System.Transaction 的一部分,但它做了更紧密的绑定,主要用于多线程场景,您可能不需要它来进行 Async Await 调用,因为只有在所有awaits都完成后才能完成。

与 TransactionScope 相关的问题必须在创建它的同一线程上处理。

解决方案在这里,这是在 .Net4.5.1 中引入的,并确保TransactionScope跨 Async 调用的使用

查询的 Sql Server 隔离级别

您所指的是大多数系统的默认设置ReadCommitted,但您当然可以调整设置以确保较低的 IsolationLevel,但也要准备好在应用程序中读取脏数据的影响

于 2018-09-03T09:37:26.920 回答