C# NHibernate:你总是要承诺吗?它在阅读时实际上做了什么?
我正在使用NHibernate与我的C#.NET项目中的数据库进行通信。当与数据库通信时,我是否总是必须提交事务?在进行读取时,这实际上做了什么?我发现自己在阅读时偶尔会忘记承诺,但一切似乎都很好C# NHibernate:你总是要承诺吗?它在阅读时实际上做了什么?,c#,.net,nhibernate,C#,.net,Nhibernate,我正在使用NHibernate与我的C#.NET项目中的数据库进行通信。当与数据库通信时,我是否总是必须提交事务?在进行读取时,这实际上做了什么?我发现自己在阅读时偶尔会忘记承诺,但一切似乎都很好 using (var tx = Session.BeginTransaction()) { var fromDb = Session.Get<User>(user.Id); Assert.AreEqual(user.Id, fromDb.Id); tx.Commit
using (var tx = Session.BeginTransaction())
{
var fromDb = Session.Get<User>(user.Id);
Assert.AreEqual(user.Id, fromDb.Id);
tx.Commit(); // <-- Necessary??
}
使用(var tx=Session.BeginTransaction())
{
var fromDb=Session.Get(user.Id);
aresequal(user.Id,fromDb.Id);
tx.Commit();//提交或回滚事务是个好主意:
开始事务启动本地事务
发送连接的事务
声明。取决于
当前事务隔离级别
设置,获取许多资源以
支持Transact-SQL语句
由连接发出的消息被锁定
直到交易完成为止
使用提交事务或
回滚事务语句。
长期未完成的交易
一段时间可以防止其他问题
用户无法访问这些已锁定的文件
资源,也可以防止日志
截断
如果您仅在事务期间读取,为什么要启动事务?
这完全没有必要
尽管如此,如果您将连接释放模式设置为“after_transaction”,则只有在提交或回滚事务后,连接才会关闭。因此,在这些情况下,如果您希望执行多个读取操作,启动事务确实很方便
事实上,我主要做的是:
Person p = null;
using( ISession s = sf.OpenSession())
{
With.Transaction (s, () => p = s.Get (1));
}
比如说
其中,“With.Transaction
”是一种实用方法,用于启动事务,执行传递的委托(操作),然后提交或回滚事务
它看起来非常像这样:
public static class With
{
public static void Transaction( ISession s, Action proc )
{
using( ITransaction thx = s.BeginTransaction () )
{
try
{
proc();
thx.Commit();
}
catch
{
thx.Rollback();
throw;
}
}
}
}
但是,我的实现仍然略有不同,因为我没有直接使用NHibernate的ISession
。
相反,我在会话
周围创建了一个包装器,在该包装器中,我还跟踪该会话的当前事务(如果有)。
通过这样做,在With.Transaction
方法中,我可以检查会话是否已经有活动事务,然后,我只在没有活动事务的情况下启动事务
(Ayende的和.Transaction
创意都有学分)。哦,我想真正的问题是“我需要一个交易来阅读吗?”-听起来你的答案是“不”?谢谢你的示例代码-看起来不错!所以你实际上必须使用一个事务?我尝试在我的示例中删除该事务,但是它在读取时找不到对象。嗯…我和ReSharper都找不到With关键字。你介意给我一个在哪里找到它的提示吗?对不起,我忘了提到。这是一个定制的类。啊,that解释了这一点。那么-我确实需要一个事务?也用于读取?并且我确实需要提交或回滚每个事务以确保释放所有资源?即使我有一个using,它将处理该事务?正确吗?因此我必须提交()或回滚()即使我有using子句来处理每一笔交易?可能已经太晚了,但答案实际上并没有回答问题,只是猜测一下这个和那个。@mikalai:还有关于BeginTransaction()的声明
只读操作不需要显式事务是完全错误的。即使在读操作中也使用显式事务被认为是良好的做法。请参阅。要回答以下问题:否,Commit()在这种情况下,
是不必要的,因为OP已经使用了using
来确保事务被正确处理,并且基础连接返回到连接池。Commit()
不做任何Dispose()
不做的只读操作。实际上,省略了Commit()
这是一个好主意,因为这样可以确保在代码出现错误时不会意外写入任何更改,从而对实体进行意外更改。Dispose()
在这种情况下会自动执行回滚。