C#.NET:TransactionScope对象是否同步了用户多个线程之间对代码的访问

本文关键字:之间 线程 代码 访问 用户 TransactionScope NET 对象 是否 同步 | 更新日期: 2023-09-27 18:30:36

TransactionScope 对象是否还会同步用户多个线程之间的代码访问?或者,它只将代码(业务运营)声明为原子(单个事务)?

详: 1. 我正在为基础架构层中的存储库实现 UnitOfWork 类,该类本身被定义为类库项目 (dll)。

  1. 存储库包含对 UnitOfWork 对象的引用,以调用其维护已添加、更改或更新的实体的分类/集合的方法。

  2. 工作单元类有一个成员函数 Commits(),其代码包装在 TransactionScope 对象中。

考虑到多个用户访问域/业务对象,那么我假设每个用户都将在其线程中运行自己的一组业务对象。

我不确定在这种情况下事务范围对象会做什么?它只是将用户线程内的多个操作标记为单个业务事务吗?或者它也在不同的用户线程之间同步代码?UnitOfWork类的代码如下:

public class UnitOfWork
{
    private Dictionary<EntityBase, IUnitOfWorkRepository> addedEntities;
    private Dictionary<EntityBase, IUnitOfWorkRepository> changedEntities;
    private Dictionary<EntityBase, IUnitOfWorkRepository> deletedEntities;
    public UnitOfWork()
    {
        this.addedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>();
        this.changedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>();
        this.deletedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>();
    }
    #region IUnitOfWork Members
    public void RegisterAdded(EntityBase entity, IUnitOfWorkRepository repository)
    {
        this.addedEntities.Add(entity, repository);
    }
    public void RegisterChanged(EntityBase entity, IUnitOfWorkRepository repository)
    {
        this.changedEntities.Add(entity, repository);
    }
    public void RegisterRemoved(EntityBase entity, IUnitOfWorkRepository repository)
    {
        this.deletedEntities.Add(entity, repository);
    }
    public void Commit()
    {
        using (TransactionScope scope = new TransactionScope())
        {
            foreach (EntityBase entity in this.deletedEntities.Keys)
            {
                this.deletedEntities[entity].PersistDeletedItem(entity);
            }
            foreach (EntityBase entity in this.addedEntities.Keys)
            {
                this.addedEntities[entity].PersistDeletedItem(entity);
            }
            foreach (EntityBase entity in this.changedEntities.Keys)
            {
                this.changedEntities[entity].PersistDeletedItem(entity);
            }
            scope.Complete();
        }
        this.deletedEntities.Clear();
        this.addedEntities.Clear();
        this.changedEntities.Clear();
    }
    #endregion
}

C#.NET:TransactionScope对象是否同步了用户多个线程之间对代码的访问

  1. 我的问题在此链接中在示例标题 P11 下得到了回答:http://www.codeproject.com/Articles/18743/Interfaces-in-C-For-Beginners

  2. 提出这个问题的原因只是为了确认在《领域驱动设计》一书的讨论中陈述的接口上的面向对象规则,其中存储库工厂类返回一种通用类型的 IRepository,这也意味着存储库工厂除了实现它之外,还将能够返回 IRepository 或任何接口 OR 类扩展 IRepository(这就是我认为 .NET 泛型的解释方式(完整的代码和讨论是下面)。

---讨论从这里开始---

--法典

using System;
using System.Collections.Generic;
using SmartCA.Infrastructure;
using SmartCA.Infrastructure.DomainBase;
using SmartCA.Infrastructure.RepositoryFramework.Configuration;
using System.Configuration;
namespace SmartCA.Infrastructure.RepositoryFramework
{
public static class RepositoryFactory
{
// Dictionary to enforce the singleton pattern
private static Dictionary < string, object > repositories = new
Dictionary < string, object > ();
/// < summary >
/// Gets or creates an instance of the requested interface. Once a
/// repository is created and initialized, it is cached, and all
/// future requests for the repository will come from the cache.
/// < /summary >
/// < typeparam name=”TRepository” > The interface of the repository
/// to create. < /typeparam >
/// < typeparam name=”TEntity” > The type of the EntityBase that the
/// repository is for. < /typeparam >
/// < returns > An instance of the interface requested. < /returns >
public static TRepository GetRepository < TRepository, TEntity > ()
where TRepository : class, IRepository < TEntity >
where TEntity : EntityBase
{
// Initialize the provider’s default value
TRepository repository = default(TRepository);
string interfaceShortName = typeof(TRepository).Name;
// See if the provider was already created and is in the cache
if (!RepositoryFactory.repositories.ContainsKey(interfaceShortName))
{
// Not there, so create it
// Get the repositoryMappingsConfiguration config section
RepositorySettings settings =
(RepositorySettings)ConfigurationManager.GetSection(RepositoryMappingConstants
.RepositoryMappingsConfigurationSectionName);
// Create the repository, and cast it to the interface specified
repository =
Activator.CreateInstance(Type.GetType(settings.RepositoryMappings[interfaceShortName]
.RepositoryFullTypeName)) as TRepository;
// Add the new provider instance to the cache
RepositoryFactory.repositories.Add(interfaceShortName, repository);
}
else
{
// The provider was in the cache, so retrieve it
repository =
(TRepository)RepositoryFactory.repositories[interfaceShortName];
}
return repository;
}
}
}

--法典

此方法的签名很有趣,因为它使用两个泛型类型参数,TRepository 和 TEntity ,但限制是 TRepository 是一个类并实现 IRepository 接口,并且 TEntity 派生自 EntityBase 类。由于存储库框架支持的接口不仅仅是 T ,因此该方法不能只返回存储库实例的 IRepository 类型。它还必须支持返回任何实现 IRepository 的接口,因为正在使用的存储库接口也可以在其中定义其他方法;这就是为什么 TRepository 被声明为泛型类型,以便工厂可以支持存储库框架要求能够传入有效的存储库接口类型并获取接口的实例(只要它在应用程序的配置文件中正确定义

)。

---讨论到此结束---

@ Adil Mughal:非常感谢,您的及时回答真的很有帮助。有关 C#.NET 上下文中术语"线程安全"的更多详细信息,我还获得了一些有用的链接,并希望在下面分享: (由此我得到的是 TransactionScope 对象是"线程安全的",这意味着 TransactionScope 对象块中的任何代码都可以由 .NET 很好地同步,并且访问代码块的多个线程不会产生并发问题, 就像它锁定代码块一样)

"线程安全"的真正含义是什么...在实际方面

是什么使方法具有线程安全性?规则是什么?

.NET 中的线程安全集合

http://www.codeproject.com/Articles/37976/Writing-Thread-Safe-Code-in-C

http://www.albahari.com/threading/part2.aspx

问候法哈尔·安瓦尔