需要帮助了解 Nhibernate 事务以及如何不重复代码(如果可能)
我知道您应该始终使用交易。我还看到 NHibernate.ITransaction 实现了 Dispose,因此我需要将 ITransaction 对象包装在 using 语句中。那么,这是否意味着对于每个非只读存储库方法(即更新、编辑...),我必须声明:
using (ITransaction _transaction = _session.BeginTransaction(//isolationlevel)) {
//procedure code here
}
有没有一种方法可以包装它(我没有看到我可以)。
另外,最好将 session.SaveOrUpdate() 方法和 transaction.Commit() 包装在 Try/Catch 中吗?
using (_transaction = _session.BeginTransaction(IsolationLevel.ReadCommitted) {
try {
_session.SaveOrUpdate(entity);
try {
_transaction.Commit();
catch (//some exception ex) {
_transaction.RollBack();
}
}
catch (//some exception ex) {
//log ex
}
}
或者是否有更好的方法,例如在同一个 try/catch 中同时使用会话和事务方法?
谢谢,
I understand that you should always use transactions. I also see that NHibernate.ITransaction implement a Dispose, so I need to wrap my ITransaction object in a using statement. So, does that mean that for every non-readonly repository method (i.e. update, edit...) I have to declare:
using (ITransaction _transaction = _session.BeginTransaction(//isolationlevel)) {
//procedure code here
}
Is there a way that I can wrap this (I am not seeing that I can).
Also, is it best that I wrap both a session.SaveOrUpdate() method and transaction.Commit() in a Try/Catch?
using (_transaction = _session.BeginTransaction(IsolationLevel.ReadCommitted) {
try {
_session.SaveOrUpdate(entity);
try {
_transaction.Commit();
catch (//some exception ex) {
_transaction.RollBack();
}
}
catch (//some exception ex) {
//log ex
}
}
Or is there a better way such as having both session and transaction methods in the same try/catch?
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
直接使用 ISession 时的推荐做法是:(即使是读取,也应该使用事务)
这基本上是创建一个工作单元。
根据您的操作上下文(Web 请求、WCF 请求),您可能希望将所有操作放在一个工作单元中。对于 Web 请求,请参阅此,对于 WCF 操作,请参阅这个。
正如 Sixto Saez 所说,调用 SaveOrUpdate 是一种味道。在大多数情况下,您会遇到以下两种情况之一:
1 您创建一个新实体并调用 session.Save(entity);
或
2 您从会话中获取一个或多个实体(使用 Get/Load 或通过查询),修改实体,nhibernate 将在会话处理时保存更改。 (除非您更改会话刷新模式,但这不是重点)。
The recommended practice when using the ISession directly is this: (you should use a transaction even for reads)
This is basically creating an unit of work.
Depending on your operation context ( web request, wcf request ) you might want to have all the operation inside a single unit of work. For web request see this for WCF operation see this.
Also as Sixto Saez said calling SaveOrUpdate is a smell. In most of the cases you have one of these two cases:
1 You create a new entity and call session.Save(entity);
or
2 You get an entity or more from the session ( with Get/Load or by query ), modify the entity and the changes will be saved by nhibernate on session disposal. ( unless you change the session flush mode but that is not the point ).
我会避免在这样的存储库中对事务进行微观管理。 这篇文章很好地解释了为什么在使用 NHibernate(或任何其他 ORM)时将数据库语义添加到存储库并不是一个好主意。最佳实践是实现工作单元模式 用于您的业务逻辑。
I would steer clear of micro-managing the transaction within a repository like that. This post does a good job of explaining why adding database semantics to your repository is not a good idea when using NHibernate (or any other ORM). The best practice is to implement a unit of work pattern for your business logic.