深入.net第四章

三层体系结构的概念


用户界面表示层(USL)
业务逻辑层(BLL)
数据访问层(DAL)

BLL将USL与DAL隔开了,并且加入了业务规则

各层的作用
1:数据数据访问层:主要是对原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据的操作,而不是数据库,具体为业务逻辑层或表示层提供数据服务.

2:业务逻辑层:主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建。

3:表示层:主要表示WEB方式,也可以表示成WINFORM方式,WEB方式也可以表现成:aspx, 如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务。
具体的区分方法

1:数据数据访问层:主要看你的数据层里面有没有包含逻辑处理,实际上他的各个函数主要完成各个对数据文件的操作。而不必管其他操作。

2:业务逻辑层:主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。

3:表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
三层结构解释

所谓三层体系结构,是在客户端与数据库之间加入了一个中间层,也叫组件层。这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,也不仅仅有B/S应用才是三层体系结构,三层是指逻辑上的三层,即使这三个层放置到一台机器上。 三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交换.

开发人员可以将应用的商业逻辑放在中间层应用服务器上,把应用的业务逻辑与用户界面分开。在保证客户端功能的前提下,为用户提供一个简洁的界面。这意味着如果需要修改应用程序代码,只需要对中间层应用服务器进行修改,而不用修改成千上万的客户端应用程序。从而使开发人员可以专注于应用系统核心业务逻辑的分析、设计和开发,简化了应用系统的开发、更新和升级工作。
那么为什么要应用“中间业务层”呢?举些例子:
     我们假设有一段登录代码,则可以这样处理Web程序,外观层负责接收前台页面的数据,然后传给中间层,中间层对数据进行处理,比如格式化,防SQL注入等等一些,这样的数据再传给数据访问层然后与数据库进行操作,比如与数据库的用户名和密码匹配等等一些代码。


“中间业务层”的用途有很多,例如:验证用户输入数据、缓存从数据库中读取的数据等等……但是,“中间业务层”的实际目的是将“数据访问层”的最基础的存储逻辑组合起来,形成一种业务规则。例如:“在一个购物网站中有这样的一个规则:在该网站第一次购物的用户,系统为其自动注册”。这样的业务逻辑放在中间层最合适: 
在“数据访问层”中,最好不要出现任何“业务逻辑”!也就是说,要保证“数据访问层”的中的函数功能的原子性!即最小性和不可再分。“数据访问层”只管负责存储或读取数据就可以了。


ASP.NET中的三层结构说明

完善的三层结构的要求是:修改表现层而不用修改逻辑层,修改逻辑层而不用修改数据层。否则你的应用是不是多层结构,或者说是层结构的划分和组织上是不是有问题就很难说.不同的应用有不同的理解,这只是一个概念的问题.
理解ASP.NET中的三层结构——为什么要分三层?

我们用三层结构主要是使项目结构更清楚,分工更明确,有利于后期的维护和升级。它未必会提升性能,因为当子程序模块未执行结束时,主程序模块只能处于等待状态。这说明将应用程序划分层次,会带来其执行速度上的一些损失。但从团队开发效率角度上来讲却可以感受到大不相同的效果。


需要说明一下,三层结构不是.NET的专利,也不是专门用在数据库上的技术。它是一种更加普适的架构设计理念。

此种架构要在数据库设计上注意表之间的关系,尽力满足主与子的关系。在功能上对用户要有一定的限制,不要表现在对于子表的删除操作一定要慎重,以免造成主表与子表的数据在逻辑上出现的主表的外键在子表中没有相对应的值。

对于表的综合查询方法是:
先对主表查询,调用主表所对应的DL。再根据主表的记录分别对每一个子表进行查询。将自表的查询结果添加的主表后,形成一个大的查询集合。
对于表的操作(增删改):
此时只对主表进行操作,调用主表对应的DL中的操作方法。
RL层是逻辑判断层,主要是对页面上传入的数据进行逻辑判断。RL层之上就是UI

如何建立一个三层体系结构解决方案

新建一个空白解决方案。然后:     
“添加”-“新建项目”-“其他项目”-“企业级模版项目”-“C#生成块”-“数据访问”(数据层,下简称D层)     
“添加”-“新建项目”-“其他项目”-“企业级模版项目”-“C#生成块”-“业务规则”(业务层,下简称C层)     
“添加”-“新建项目”-“其他项目”-“企业级模版项目”-“C#生成块”-“Web用户界面”(界面层,下简称U层)     
右键点“解决方案”-“项目依赖项”,设置U依赖于D、C,C依赖于D。     
对U添加引用D、C,对C添加引用D。     
到此为止,一个三层的架子建立起来了。我上面说的很具体很“傻瓜”,知道的人觉得我废话,其实我这段时间很强烈的感觉到非常多的人其实对这个简单的过程完全不了解。虽然不反对建2个“空项目”和1个“Asp    net    Web应用程序项目”也可以作为3层的框架,而且相当多的人认为其实这些“企业级模板项目”其实就是个空项目,这是一个误区。没错,企业级模板项目你从解决方案资源管理器里看它是个什么也没有的,但是你可以用记事本打开项目文件,看见不同了吧??有些东西在背后,你是看不见的,不过系统已经做好了。也就是说,如果你在C层里的某个类里“using    System    Data    SqlClineit”,或者使用一个SqlConnection对象,编译时候不会出错,但是会在“任务列表”里生成一些“策略警告”,警告你在C层里不要放应该放在D层的东西(虽然就程序来说没错,但是可读性可维护性就打了折扣)而这种功能,空项目是无法給你的。
在新TraceLWord3中,应用了“企业级模板项目”。把原来的LWordTask.cs,并放置到一个单一的项目里,项目名称为:AccessTask。解决方案中又新建了一个名称为:InterService的项目,该项目中包含一个LWordService.cs程序文件,它便是“中间业务层”程序。为了不重复命名,TraceLWord3的网站被放置到了WebUI项目中。更完整的代码,可以在CodePackage/TraceLWord3目录中找到——     

面象对象与实际的结合

我们知道建桥需要砖块,应该是先准备好砖再来建桥,不过为了讲解上的顺序性和连贯性,简单性。我们先建桥,建的过程中需要砖块再现做,这样就不会多出来“桥不需要的东西”。注意在实际中,还是应该先准备砖块。
     
U层其实就是桥,C层是砖块,D层是原料(石头、沙子)。这也解释前面为什么U层要引用、依赖D层(而不是U对C,C对D的层次),因为桥除了需要砖头,其实也需要石头沙子。
“三层结构”的缺点







一 事务处理介绍 
事务是这样一种机制,它确保多个SQL语句被当作单个工作单 
元来处理。事务具有以下的作用: 
* 一致性:同时进行的查询和更新彼此不会发生冲突,其他 
用户不会看到发生了变化但尚未提交的数据。 
* 可恢复性:一旦系统故障,数据库会自动地完全恢复未完 
成的事务。 

二 事务与一致性 
事务是完整性的单位,一个事务的执行是把数据库从一个一 
致的状态转换成另一个一致的状态。因此,如果事务孤立执行时 
是正确的,但如果多个事务并发交错地执行,就可能相互干扰, 
造成数据库状态的不一致。在多用户环境中,数据库必须避免同 
时进行的查询和更新发生冲突。这一点是很重要的,如果正在被 
处理的数据能够在该处理正在运行时被另一用户的修改所改变, 
那么该处理结果是不明确的。 
不加控制的并发存取会产生以下几种错误: 
1 丢失修改(lost updates) 
当多个事务并发修改一个数据时,不加控制会得出错误的结 
果,一个修改会覆盖掉另一个修改。 
2 读的不可重复性 
当多个事务按某种时间顺序存取若干数据时,如果对并发存 
取不加控制,也会产生错误。 
3 脏读(DIRDY DATA),读的不一致性 
4 光标带来的当前值的混乱 
事务在执行过程中它在某个表上的当前查找位置是由光标表 
示的。光标指向当前正处理的记录。当处理完该条记录后,则指 
向下一条记录。在多个事务并发执行时,某一事务的修改可能产 
生负作用,使与这些光标有关的事务出错。 
5 未释放修改造成连锁退出 
一个事务在进行修改操作的过程中可能会发生故障,这时需 
要将已做的修改回退(Rollback)。如果在已进行过或已发现错 
误尚未复原之前允许其它事务读已做过修改(脏读),则会导致 
连锁退出。 
6 一事务在对一表更新时,另外的事务却修改或删除此表的 
定义。 
数据库会为每个事务自动地设置适当级别的锁定。对于前面 
讲述的问题:脏读、未释放修改造成的连锁退出、一事务在对一 
表更新时另外的事务却修改或删除此表的定义,数据库都会自动 
解决。而另外的三个问题则需要在编程过程中人为地定义事务或 
加锁来解决。 
三 事务和恢复 
数据库本身肩负着管理事务的责任。事务是最小的逻辑工作 
单元,在这个工作单元中,对数据库的所有更新工作,要么必须 
全部成功,要么必须全部失败(回退)。只要应用程序指定了某 
段程序为一个事务并做了相应的处理(提交或回退),数据库系 
统会自动维护事务本身的特性。 

四 ORACLE数据库的事务定义 
ORACLE事务从COMMIT、ROLLBACK、连接到数据库或开始第一 
条可执行的SQL语句时开始,到一条COMMIT、ROLLBACK语句或退出 
数据库时结束。如果在一个事务中包含DDL语句,则在DDL语句的 
前后都会隐含地执行COMMIT语句,从而开始或结束一个事务。 
如果一个事务由于某些故障或者由于用户改变主意而必须在 
提交前取消它,则数据库被恢复到这些语句和过程执行之前的状 
态。 
利用ROLLBACK语句可以在COMMIT命令前随时撤消或回退一个 
事务。可以回退整个事务,也可以会退部分事务,但是不能回退 
一个已经被提交的事务。回退部分事务的ROLLBACK命令为: 
ROLLBACK to savepoint 存储点名 
存储点是用户放入事务中的标记,用来表示一个可被回退的 
位置。存储点通过在事务中放入一个SAVEPOINT命令而被插入。该 
命令的语法是: 
SAVEPOINT 存储点名 
如果在ROLLBACK语句中没有给出存储点名,则整个事务被回 
退。 
五 SYBASE数据库的事务定义 
SYBASE通过使用BEGIN TRANsaction和COMMIT TRANsaction命令指 
示SQL将任意数目的语句作为一个单元来处理。ROLLBACK TRANsaction 
命令则允许用户恢复到事务的开始,或恢复到事务内部已经被用SAVE 
TRANsaction命令定义的存储点上。 
BEGIN TRANsaction和COMMIT TRANsaction能够包含任意数目的SQL 
语句和存储过程,方法很简单: 
BEGIN TRANsaction [事务名称] 
COMMIT TRANsaction 
如果一个事务由于某些故障或者由于用户改变主意而必须在提交 
前取消它,则数据库被恢复到这些语句和过程执行之前的状态。 
利用ROLLBACK TRANsaction命令可以在COMMIT TRANsaction命令 
前随时回退一个事务。可以回退整个事务,也可以回退部分事务,但 
是不能回退一个已经被提交的事务。ROLLBACK TRANsaction命令为: 
ROLLBACK TRANsaction [事务名|存储点名] 
存储点名是用户放入事务中的标记,用来表示一个可以被回退的 
位置。存储点名通过在事务中放入一个SAVE TRANsaction命令而被插 
入。该命令的句法是: 
SAVE TRANsaction 存储点名 
如果在ROLLBACK TRANsaction中没有给出存储点名或事务名,则 
事务被回退到批处理中的第一个BEGIN TRANsaction语句处。
---------------------------------------------------------------------------------------------------------------------------------


Ado.Net事务处理。
在ADO.NET 中,可以使用Connection 和Transaction 对象来控制事务。若要执行事务,请执行下列操作:
• 调用Connection 对象的BeginTransaction 方法来标记事务的开始。
• 将Transaction 对象分配给要执行的Command的Transaction 属性。
• 执行所需的命令。
• 调用Transaction 对象的Commit 方法来完成事务,或调用Rollback 方法来取消事务。
当然ADO.NET事务处理有优点和缺点,运用起来看具体情况了。
• 优点:
– 简单性
– 和数据据事务差不多的快
– 独立于数据库,不同数据库的专有代码被隐藏了
• 缺点:
– 事务不能跨越多个数据库连接
– 事务执行在数据库连接层上,所以需要在事务过程中维护一个数据库连接。
下边我们看一个例子,建立一个页面,同样简单,只需要一个按钮,然后编程:
 1using System;
 2using System.Data;
 3using System.Configuration;
 4using System.Collections;
 5using System.Web;
 6using System.Web.Security;
 7using System.Web.UI;
 8using System.Web.UI.WebControls;
 9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11using System.Data.SqlClient;
12
13namespace WebApplication1
14{
15    public partial class AdoAction : System.Web.UI.Page
16    {
17        protected void Page_Load(object sender, EventArgs e)
18        {
19
20        }
21
22        protected void btn_Click(object sender, EventArgs e)
23        {
24            SqlConnection con = new SqlConnection();
25            con.ConnectionString=ConfigurationManager.ConnectionStrings["DSN"].ConnectionString;
26            con.Open();
27            //启动一个事务。
28            SqlTransaction myTran = con.BeginTransaction();
29            //为事务创建一个命令,注意我们执行双条命令,第一次执行当然成功。我们再执行一次,失败。
30            //第三次我们改其中一个命令,另一个不改,这时候事务会报错,这就是事务机制。
31            SqlCommand myCom = new SqlCommand();
32            myCom.Connection = con;
33            myCom.Transaction = myTran;
34            try
35            {
36                myCom.CommandText = "insert into SqlAction values ('测试2','111')";
37                myCom.ExecuteNonQuery();
38                myCom.CommandText = "insert into SqlAction values ('测试3','111')";
39                myCom.ExecuteNonQuery();
40                myTran.Commit();
41                Response.Write("成功执行");
42
43            }
44            catch (Exception Ex)
45            {
46                myTran.Rollback();
47                //创建并且返回异常的错误信息
48                Response.Write(Ex.ToString());
49                Response.Write("写入数据库失败");
50            }
51            finally
52            {
53                con.Close();
54            }
55 
56        }
57
58
59    }
60} 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值