长会话的版本并发控制.冬眠.ASP.NET MVC

本文关键字:ASP NET MVC 冬眠 并发控制 会话 版本 | 更新日期: 2023-09-27 18:25:26

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

2( 如果项目被锁定或是否发生回滚,如何通知用户?

3( 假设我已经将所有需要的标记(如 optimistic-locking="false" 以排除我不想参与比较的属性(添加到我的实体映射文件中,并在实体类上定义了一个 Version 属性来处理并发控制。这就足够了吗,所有的东西都在NHibernate内部/由处理。还是应该存在其他修改?例如在Repository

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<>));
    }
}

我正在使用包含多个事务的长会话。

谢谢!

长会话的版本并发控制.冬眠.ASP.NET MVC

您的存储库永远不应处理事务范围。这是一个完全不同的要求,存储库无法知道事务应该具有什么边界。

事务应由基础结构代码在外部的某个地方处理。如果您使用的是 ASP.NET MVC - 操作过滤器是合适的(请参阅实现是夏普架构项目(。

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

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

您在此处缺少"工作单元"模式。