C# 长会话的版本并发控制。NHibernate。ASP.NETMVC

C# 长会话的版本并发控制。NHibernate。ASP.NETMVC,c#,asp.net,asp.net-mvc,nhibernate,concurrency,C#,Asp.net,Asp.net Mvc,Nhibernate,Concurrency,1) 什么是更合适/常用的并发控制方法?悲观还是乐观 2) 如果某个项目被锁定或是否发生了回滚,如何通知用户 3) 假设我已经向实体映射文件添加了所有需要的标记(如optimistic locking=“false”以排除我不想参与比较的属性),并在实体类上定义了一个Version属性来处理并发控制。这就足够了,所有的东西都在NHibernate内部处理了吗。或者应该进行额外的修改?例如在存储库中 public class Repository<T> : IRepository<

1) 什么是更合适/常用的并发控制方法?悲观还是乐观

2) 如果某个项目被锁定或是否发生了回滚,如何通知用户

3) 假设我已经向实体映射文件添加了所有需要的标记(如
optimistic locking=“false”
以排除我不想参与比较的属性),并在实体类上定义了一个
Version
属性来处理并发控制。这就足够了,所有的东西都在NHibernate内部处理了吗。或者应该进行额外的修改?例如在
存储库中

public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
    private ISession session;

    public Repository(ISession session)
    {
        this.session = session;
    }

    public T Get(Guid id)
    {            
        return this.session.Get<T>(id);            
    }
    public IQueryable<T> Get(Expression<Func<T, Boolean>> predicate)
    {
        return this.session.Query<T>().Where(predicate);            
    }
    public IQueryable<T> Get()
    {
        return this.session.Query<T>();            
    }
    public T Load(Guid id)
    {
        return this.session.Load<T>(id);
    }
    public void Add(T entity)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Save(entity);
            transaction.Commit();
        }
    }
    public void Remove(T entity)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Delete(entity);
            transaction.Commit();
        }
    }
    public void Remove(Guid id)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Delete(this.session.Load<T>(id));
            transaction.Commit();
        }
    }
    public void Update(T entity)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Update(entity);
            transaction.Commit();
        }
    }
    public void Update(Guid id)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Update(this.session.Load<T>(id));
            transaction.Commit();
        }
    }
}

// DI
public class DataAccessModule : Ninject.Modules.NinjectModule
{
    public override void Load()
    {
        this.Bind<ISessionFactory>()
            .ToMethod(c => new Configuration().Configure().BuildSessionFactory())
            .InSingletonScope();

        this.Bind<ISession>()
            .ToMethod(ctx => ctx.Kernel.TryGet<ISessionFactory>().OpenSession())
            .InRequestScope();

        this.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
    }
}
公共类存储库:IRepository,其中T:AbstractEntity,IAggregGateRoot
{
非公开会议;
公共存储库(ISession会话)
{
this.session=会话;
}
公共无法获取(Guid id)
{            
返回此.session.Get(id);
}
公共IQueryable Get(表达式谓词)
{
返回this.session.Query().Where(谓词);
}
公共IQueryable Get()
{
返回此.session.Query();
}
公共T加载(Guid id)
{
返回此.session.Load(id);
}
公共无效添加(T实体)
{            
使用(var transaction=this.session.BeginTransaction())
{
此.session.Save(实体);
Commit();
}
}
公共无效删除(T实体)
{            
使用(var transaction=this.session.BeginTransaction())
{
此.session.Delete(实体);
Commit();
}
}
公共无效删除(Guid id)
{            
使用(var transaction=this.session.BeginTransaction())
{
this.session.Delete(this.session.Load(id));
Commit();
}
}
公共无效更新(T实体)
{            
使用(var transaction=this.session.BeginTransaction())
{
此.session.Update(实体);
Commit();
}
}
公共无效更新(Guid id)
{            
使用(var transaction=this.session.BeginTransaction())
{
this.session.Update(this.session.Load(id));
Commit();
}
}
}
//DI
公共类DataAccessModule:Ninject.Modules.NinjectModule
{
公共覆盖无效负载()
{
this.Bind()
.ToMethod(c=>newconfiguration().Configure().BuildSessionFactory())
.InSingletonScope();
this.Bind()
.ToMethod(ctx=>ctx.Kernel.TryGet().OpenSession())
.InRequestScope();
将(typeof(IRepository))绑定到(typeof(Repository));
}
}
我正在使用多个事务的长会话


谢谢

存储库不应处理事务范围。这是一个完全不同的需求,存储库不知道事务应该有什么边界

事务应该在基础架构代码之外的某个地方处理。如果您使用的是ASP.NET MVC,那么操作过滤器是合适的(请参阅实现是Sharp架构项目)

如果是ASP.NET,则可以应用模块或全局asax处理


但不要在存储库中处理它,因为它的抽象非常泄漏,您需要向调用方公开边界

存储库不应处理事务范围。这是一个完全不同的需求,存储库不知道事务应该有什么边界

事务应该在基础架构代码之外的某个地方处理。如果您使用的是ASP.NET MVC,那么操作过滤器是合适的(请参阅实现是Sharp架构项目)

如果是ASP.NET,则可以应用模块或全局asax处理


但不要在存储库中处理它,因为它的抽象非常泄漏,您需要向调用方公开边界

此处缺少“”图案。

此处缺少“”图案。

确定。我已经研究了为什么在存储库中公开事务是一种不好的做法。现在我有两个问题。我希望我的每个请求的
会话
方案保持不变。如果逻辑保持不变,我应该考虑哪些问题?第二。有很多方法可以实现基于操作过滤器的事务处理或其他方法。但其中大多数是有争议的,一点也不清楚。那么你能给我一个前后一致的解释吗。谢谢!看看这里,这可能是我看过的最好的方向。谢谢但我仍然对我得到的解决方案所提供的问题感到好奇。我将面临哪些问题,例如对数据库的错误写入或其他问题?你能帮我吗?我这么问是因为我几乎已经建立了一个项目,可能是因为数据访问策略实现中的错误。您的实现清楚地说明了策略“最后一个胜出”,所以您唯一能遇到的问题是,一个人的更改将被另一个人覆盖,但在其他情况下,您将得到相同的结果。如果您几乎实现了所有功能,并且在测试中没有任何问题,我认为您不会在生产中使用它们。。。但谁能肯定呢?:)如果我对修改查询使用
StaleObjectStateException cathing
重构
Repository
,并给它一个适当的隔离级别(目前我不知道哪个更好)。我已经在实体上使用版本控制了。好的。我已经研究了为什么在存储库中公开事务是一种不好的做法。现在我有两个问题。我希望我的每个请求的
会话
方案保持不变。如果逻辑保持不变,我应该考虑哪些问题?第二。有很多方法可以实现基于操作过滤器的事务处理或其他方法。但其中大多数是有争议的,不清楚的