C# Nhibernate-锁DB

C# Nhibernate-锁DB,c#,nhibernate,orm,C#,Nhibernate,Orm,我第一次使用Nhibernate,我注意到当我调用BeginTransaction方法时,它会锁定我的数据库。 相反,实体框架(ObjectContext或DbContext)保持内存中的所有更改,并且如果不锁定数据库中的任何内容而不发生错误,则SaveChange方法可以完美地工作 Nhibernate是否有一些功能,如EF?如果您使用的是乐观并发,那么您可以执行以下操作: MyEntity myEntity; using(var scope = new TransactionScope(Tr

我第一次使用Nhibernate,我注意到当我调用BeginTransaction方法时,它会锁定我的数据库。 相反,实体框架(ObjectContext或DbContext)保持内存中的所有更改,并且如果不锁定数据库中的任何内容而不发生错误,则SaveChange方法可以完美地工作


Nhibernate是否有一些功能,如EF?

如果您使用的是乐观并发,那么您可以执行以下操作:

MyEntity myEntity;
using(var scope = new TransactionScope(TransactionScopeOption.Suppress))
using(var session = sessionFactory.OpenSession())
{
    myEntity = session.Get<MyEntity>(id);
    scope.Complete();
}

// No longer in a transaction...
myEntity.Add(something);
myEntity.Update(somethingElse);

// Later, possibly in another request...

using(var scope = new TransactionScope(TransactionScopeOption.Required))
using(var session = sessionFactory.OpenSession())
{
    session.Update(myEntity);
    scope.Complete();
}
MyEntity MyEntity;
使用(var scope=newtransactionscope(TransactionScopeOption.Suppress))
使用(var session=sessionFactory.OpenSession())
{
myEntity=session.Get(id);
scope.Complete();
}
//不再在事务中。。。
添加(某物);
myEntity.Update(somethingElse);
//稍后,可能在另一个请求中。。。
使用(var范围=新TransactionScope(TransactionScopeOption.Required))
使用(var session=sessionFactory.OpenSession())
{
更新会议(myEntity);
scope.Complete();
}
只要事务处于打开状态(如上所述,在隔离级别上解除隔离),您就可能在初始选择中涉及的表和键上拥有共享锁,这将阻止对这些表的更新,直到事务完成。如果要避免使用这些锁,可以抑制读取事务,执行修改,然后稍后尝试更新对象。实体上的版本号应保护您免受丢失的更新


请注意,您不必抑制读取事务。如果要阻止,直到提交所有写入操作,只要与更新事务分离并尽快完成,您仍然可以要求围绕读取执行事务

您可能想玩
IsolationLevel
。默认值为
ReadCommitted
,但您可以在
BeginTransaction
上更改它。我不得不在某个项目上使用快照。您衡量过性能并确定事务是一个瓶颈吗?我讨厌任何关于资源锁定的事情。但我承认有时它们是有用的,不过我更喜欢类似实体框架的行为作为默认行为。我在哪里可以在Nhibernate中设置IsolationLevel选项?From:
仅处理针对数据源的操作。在对象上下文中对对象所做的更改不会被处理
。我将其解释为查询是在事务中进行的,因此
SaveChanges()
是在同一事务中进行的=与nhibernate的行为相同。EF如何确保数据库中没有任何内容被覆盖?当然。它是。那么,我怎样才能在NHIbernate中得到同样的行为呢?我想更改许多和任何对象,添加、删除、编辑,最后调用“SaveChange”方法。我看到的所有instaed示例都从begin tansaction(锁定数据库)开始,然后更改一些实体,最后调用commit。关于DB锁定的范围时间是不同的。谢谢你的回答,但我不喜欢。我认为最好实现实体框架已经实现的东西,例如,我可以用我的自定义对象保存内存中的所有更改,最后调用NHibernate的BeginTransaction提交。通过这种方式,我将完全按照EF所做的去做。您认为呢?如果您正在保存一个新对象,那么您可以在打开会话和启动事务之前构建对象图。如果您正在更新一个对象,执行“内存中”更新而不持有锁的唯一方法是:1)在没有事务的情况下读取对象(抑制它);2) 读取事务中的对象并在更新对象之前结束事务;或者3)放松事务隔离级别(这仍然会保留一些锁)。如果将对象图与会话分离是一个问题,则可以在单个会话中使用多个事务。