C#.NET:TransactionScope对象是否同步了用户多个线程之间对代码的访问
本文关键字:之间 线程 代码 访问 用户 TransactionScope NET 对象 是否 同步 | 更新日期: 2023-09-27 18:30:36
TransactionScope 对象是否还会同步用户多个线程之间的代码访问?或者,它只将代码(业务运营)声明为原子(单个事务)?
详: 1. 我正在为基础架构层中的存储库实现 UnitOfWork 类,该类本身被定义为类库项目 (dll)。
-
存储库包含对 UnitOfWork 对象的引用,以调用其维护已添加、更改或更新的实体的分类/集合的方法。
-
工作单元类有一个成员函数 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
}
-
我的问题在此链接中在示例标题 P11 下得到了回答:http://www.codeproject.com/Articles/18743/Interfaces-in-C-For-Beginners
-
提出这个问题的原因只是为了确认在《领域驱动设计》一书的讨论中陈述的接口上的面向对象规则,其中存储库工厂类返回一种通用类型的 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
---讨论到此结束---
@ 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
问候法哈尔·安瓦尔