C# 长会话的版本并发控制。NHibernate。ASP.NETMVC
1) 什么是更合适/常用的并发控制方法?悲观还是乐观 2) 如果某个项目被锁定或是否发生了回滚,如何通知用户 3) 假设我已经向实体映射文件添加了所有需要的标记(如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<
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
,并给它一个适当的隔离级别(目前我不知道哪个更好)。我已经在实体上使用版本控制了。好的。我已经研究了为什么在存储库中公开事务是一种不好的做法。现在我有两个问题。我希望我的每个请求的会话
方案保持不变。如果逻辑保持不变,我应该考虑哪些问题?第二。有很多方法可以实现基于操作过滤器的事务处理或其他方法。但其中大多数是有争议的,不清楚的