业务逻辑层的设计(三)——事务的考虑

写博文不容易,坚持写更不容易,写得快更加不容易。

如果要写,必定是自己肚子里有货;坚持写,是学习能力的体现;又要工作又要持续学习,不写得快怎么能行呢。

原本想把我的数据访问层也一起公开的,但是有朋友劝我不要发布。

他告诉我:网上发布的多数是贴贴Demo,框架只有在实战中才有存在价值,发布出来一般也没人有那个耐心去看,早就沉没在信息的海洋里了。

但我还是想把业务层都写完了。

 

事务管理应该放在哪一层做

事务的开始与提交应该放在哪里呢?业务逻辑层还是数据访问层?

我以为,数据访问层需要,业务逻辑层也需要。

数据访问层的仓储(Repository)做细粒度的事务,业务逻辑层做相对较粗的事务。

那么具体如何实现呢?

 

Repository中得事务,下面分别是3个版本的事务,原生SQL,NHibernate,Entity Framework,我之所以写3个版本,是想证明数据访问层随时可以切换,而业务层绝不能受制于它,无论拼接SQL还是HQL,都不是一个很好的习惯。

    public class UserRepository : BaseRepository,IUserRepository
    {
        public void SaveUser(User user)
        {
            //ADO.NET事务开始
            //省略执行SQL语句的操作……
            //ADO.NET事务提交
        }
    }
        public void SaveUser(User user)
        {
            ITransaction tran = Session.BeginTransaction();
            Session.Save(user);
            tran.Commit();
            tran.Dispose();
        }
        public void SaveUser(User user)
        {
            using (TransactionScope tx = new TransactionScope())
            {
                context.AddObject("User",user);
                tx.Complete();
                context.AcceptAllChanges();
            }
        }


业务层的事务,这里引入了System.Transactions命名空间,userRep.SaveUser(user2);这段就是刚才看到的,包含了一个事务的仓储,

执行tx.Complete();才会走完这个事务,如果在using中出现了异常,那么所有事务都将回滚。其实是一个嵌套事务。

        [Test]
        public void TranTest()
        {
            IDataContext context = DataContextFactory.GetDataContext();
            Department dept = context.GetByID<Department>(1);
            User user1 = new User() { LoginName = "adama1", Name = "adama1", Password = "123123", Department = dept };
            User user2 = new User() { LoginName = "adama2", Name = "adama2", Password = "123123", Department = dept };
            IUserRepository userRep = RepostoryFactory.GetFor<User>() as IUserRepository;
            using (TransactionScope tx = new TransactionScope())
            {
                context.Add(user1);
                userRep.SaveUser(user2);
                tx.Complete();
            }
        }

 

上面的context不是EF的上下文,是DAL封装起来的上下文,可以给NHibernate和EF切换的统一接口。

无论如何,架构设计者都不能让业务逻辑层感觉到ORM工具的存在,如果无法做到,那么定义了IRepository接口就成了摆设。

在实际使用中,上面的例子完全可以加入上一篇提到的验证业务规则,它可以应付更加复杂的逻辑的。

 

结尾:这几篇博文真的非常偏重于领域驱动,但有许多公司甚至连ORM是什么都不知道,用EF的公司只能说明技术总监很潮。

下一次试着用一些简单传统的设计,也就不需要这么多的前置技能,设计更加随意。

本篇开始出现许多绝对性的词语(无论,绝对,肯定),通常绝对性的话语都是错的,因为世事无绝对。

但我还是那句话“写技术博文已经很理性了,为什么不能多加入一些感性的元素”。

不知道还有没有机会写下去,心里有个声音:英语已经等不急了,快去看它吧。


<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值