简体   繁体   English

Nhibernate事务:避免服务层中的Nhibernate依赖

[英]Nhibernate transactions:Avoiding Nhibernate dependency in the service layer

One of practices advocated by Nhibernate experts is to do all actions in inside a transaction. Nhibernate专家倡导的一种做法是在交易中所有行动。

In a typical 3 tier web architecture, Nhibernate depedency is limited the data layer. 在典型的3层Web架构中,Nhibernate依赖性受限于数据层。

In such a case is it fine to use 在这种情况下,使用起来很好

  using (var tr = NHibernateSession.Current.BeginTransaction()) {

at the controller level. 在控制器级别。 Won't this bring in a dependency on Nhibernate to the service layer? 这不会将Nhibernate依赖于服务层吗?

One way around this is the wrap the NHibernate session and transaction semantics in your own abstrated Interface / implementation class. 解决这个问题的一种方法是将NHibernate会话和事务语义包装在您自己的抽象接口/实现类中。 This way if you ever wanted to say, switch to Linq2Sql, you could create a L2S implementation. 这样,如果你想说,切换到Linq2Sql,你可以创建一个L2S实现。 However, this still means that transaction semantics will still be in the service layer, but not NHibernate specific calls. 但是,这仍然意味着事务语义仍将在服务层中,而不是NHibernate特定的调用。 Google IRepository<T> for many examples of how to do this. 有关如何执行此操作的许多示例,请IRepository<T> Google IRepository<T>

However, if you don't plan on switching out your ORM in the future, one could argue that having NHibernate in the service layer isn't necessarily a bad thing since NHibernate in itself is the abstraction over the data layer. 但是,如果您不打算在将来切换ORM,可以说在服务层中使用NHibernate并不一定是坏事,因为NHibernate本身就是对数据层的抽象。

I'm also looking to do this but haven't settled on an approach yet for lack of time and some YAGNI. 我也希望这样做,但由于缺乏时间和一些YAGNI尚未确定方法。

Here is some code I haven't yet tested, but adapted from the open source SharpArch project. 这是一些我尚未测试的代码,但改编自开源的SharpArch项目。 I like the interface alot, but I may have changed the NHib implementation a bit, as there are some things I don't love about SharpArch's repository implementation, but you can judge for yourself. 我喜欢这个界面很多,但我可能已经改变了一些NHib实现,因为有些事情我不喜欢SharpArch的存储库实现,但你可以自己判断。

Of course using NHib session.BeginTransaction() introdues NHib dependencies, and not abstracting this out seems at odds with abstracting out IRepository and everything else. 当然使用NHib session.BeginTransaction()引入NHib依赖项,而不是抽象出来似乎与抽象出IRepository和其他所有内容不一致。 I for one would be very interested in what you conclude as a useful abstraction of transactions. 我会对你作为有用的交易抽象的结论非常感兴趣。

HTH, HTH,
Berryl Berryl

public interface IDbContext {
    void CommitChanges();
    IDisposable BeginTransaction();
    void CommitTransaction();
    void RollbackTransaction();
}

public class DbContext : IDbContext {
    private readonly ISession _session;

    public DbContext(ISession session)
    {
        Check.RequireNotNull<ISession>(session);
        _session = session;
    }

    public void CommitChanges() { _session.Flush(); }

    public IDisposable BeginTransaction() { return _session.BeginTransaction(); }

    public void CommitTransaction() { _session.Transaction.Commit(); }

    public void RollbackTransaction() { _session.Transaction.Rollback(); }

}

Calls to some static singleton strewn about like that doesn't seem like a good idea to me. 对某些静态单身人士的呼唤似乎对我来说似乎不是一个好主意。 Perhaps it would be better to add a dependency on your own "ITransactionFactory" and leave the NHibernate specific code inside the TransactionFactory implementation. 也许最好在您自己的“ITransactionFactory”上添加依赖项,并将NHibernate特定代码留在TransactionFactory实现中。

For SharpArchitecture specifically, there is the TransactionAttribute action filter that is designed to wrap your action methods inside transactions. 特别是对于SharpArchitecture,有一个TransactionAttribute动作过滤器,用于将您的动作方法包装在事务中。

Concerning assembly references to NHibernate, that's not something I would personally worry about. 关于NHibernate的汇编引用,这不是我个人担心的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM