学习笔记 --- BLL层事物、asp.net异常处理

1. BLL层事务:

简单的BLL层的事物, 使用TransactionScope就可以, 在TransactionScope的代码块中, 无错误就调用TransactionScope对象上的Complete()方法提交数据, 若有错就自动回滚.
值得注意的是, 对于使用DataSet、DataTable等无连接存取数据时, 如果要实现BLL层事物, 则需要给出一个状态为Open的Connection. 详见文章中的System.Transactions and ADO.NET 2.0 (英文的).

//示例代码:
//DAL/Utility.cs

View Code
    
    
    
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.SqlClient;
using System.Data;

namespace DAL
{
public class Utility
{
public static void ExeNoQuery( string sqlStr, string constr, CommandType type, params SqlParameter[] param)
{
SqlConnection con
= new SqlConnection(constr);
SqlCommand com
= new SqlCommand();
com.Connection
= con;
com.CommandType
= type;
com.CommandText
= sqlStr;
if (type == CommandType.StoredProcedure)
{
for ( int i = 0 ; i < param.Length; i ++ )
{
if (param[i].Value as string == string .Empty)
{
param[i].Value
= DBNull.Value;
}
com.Parameters.Add(param[i]);
}

}
try
{
con.Open();
com.ExecuteNonQuery();

}
catch (Exception ex)
{
throw ;
}

finally
{
if (con.State == ConnectionState.Open)
con.Close();
}
}
public static DataSet ExeDataSet( string sqlStr, string constr, CommandType type, params SqlParameter[] param)
{
SqlConnection con
= new SqlConnection(constr);
SqlCommand com
= new SqlCommand();
com.Connection
= con;
com.CommandType
= type;
com.CommandText
= sqlStr;
if (type == CommandType.StoredProcedure)
{
for ( int i = 0 ; i < param.Length; i ++ )
com.Parameters.Add(param[i]);
}
DataSet ds
= new DataSet();
SqlDataAdapter da
= new SqlDataAdapter();
da.SelectCommand
= com;

try
{
da.Fill(ds);

}
catch (Exception ex)
{

}

return ds;

}
public static SqlDataReader ExeQuery( string sqlStr, string constr, CommandType type, params SqlParameter[] param)
{
SqlDataReader dr
= null ;
SqlConnection con
= new SqlConnection(constr);
SqlCommand com
= new SqlCommand();
com.Connection
= con;
com.CommandType
= type;
com.CommandText
= sqlStr;
if (type == CommandType.StoredProcedure)
{
for ( int i = 0 ; i < param.Length; i ++ )
com.Parameters.Add(param[i]);

}
try
{
con.Open();
dr
= com.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{

}

return dr;

}
}
}

//DAL/EmployeeDAL.cs

View Code
    
    
    
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DAL
{
public class EmployeeDAL
{
private static readonly string constr = System.Configuration.ConfigurationManager.ConnectionStrings[ " MsSql " ].ConnectionString;
public void InsertEmployee( string employeename, int departmentid)
{
System.Data.SqlClient.SqlParameter p_name
= new System.Data.SqlClient.SqlParameter( " @ename " , System.Data.SqlDbType.NVarChar, 30 );
p_name.Value
= employeename;
System.Data.SqlClient.SqlParameter p_depid
= new System.Data.SqlClient.SqlParameter( " @depid " , System.Data.SqlDbType.Int);
p_depid.Value
= departmentid;
Utility.ExeNoQuery(
" SP_AddEmployee " , constr, System.Data.CommandType.StoredProcedure, p_name, p_depid);
}
}
}

//DAL/DepartmentDAL.cs

View Code
    
    
    
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DAL
{
public class DepartmentDAL
{
private static readonly string constr = System.Configuration.ConfigurationManager.ConnectionStrings[ " MsSql " ].ConnectionString;
public int InsertDepartment( string departmentname)
{
int depid = - 1 ;
System.Data.SqlClient.SqlParameter p_name
= new System.Data.SqlClient.SqlParameter( " @depname " , System.Data.SqlDbType.NVarChar, 30 );
p_name.Value
= departmentname;

System.Data.SqlClient.SqlParameter p_id
= new System.Data.SqlClient.SqlParameter( " @return_value " , System.Data.SqlDbType.Int);
p_id.Direction
= System.Data.ParameterDirection.ReturnValue;

Utility.ExeNoQuery(
" SP_AddDepartment " , constr, System.Data.CommandType.StoredProcedure, p_name, p_id);
depid
= ( int )p_id.Value;
return depid;
}
}
}

//BLL/DepartmentBLL.cs

View Code
    
    
    
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BLL
{
public class DepartmentBLL
{
#region 全局变量
DAL.DepartmentDAL dd
= new DAL.DepartmentDAL();
DAL.EmployeeDAL ed
= new DAL.EmployeeDAL();
#endregion

public void AddDepartmentWithSomeEmployees( string departmentname, params string [] employeenames)
{
// 添加System.Transactions.dll.
// 开启分布式事务支持:把 C:\WINDOWS\system32\dtclog 这个目录重命名(如果有),然后重新建立该目录。然后在命令行下: msdtc -resetlog
// 在“开始”->“设置”->“控制面板”->“管理工具”->“组件服务”中,“控制台根目录”->“组件服务”->“计算机”->“我的电脑”->“COM+应用程序”中,有一个“IIS Out-Of-Process Pooled”鼠标右键“属性”--“标识”--把“此用户”调整为“交互式用户--目前已登录的用户”。然后“确定”,再鼠标右键“属性”--“启动.

using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())
{
int departmentid = dd.InsertDepartment(departmentname);
for ( int i = 0 ; i < employeenames.Length; i ++ )
{
ed.InsertEmployee(employeenames[i], departmentid);
}
ts.Complete();
}
}
}
}

//UI/Default.aspx

View Code
    
    
    
    
<% @ Page Language = " C# " AutoEventWireup = " true " CodeFile = " Default.aspx.cs " Inherits = " _Default " %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >

< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title ></ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< span > 部门: &nbsp; </ span >< asp:TextBox ID ="txt_dep" runat ="server" ></ asp:TextBox >
< hr />
< span > 员工1: &nbsp; </ span >< asp:TextBox ID ="txt_emp1" runat ="server" ></ asp:TextBox >
< span > 员工2: &nbsp; </ span >< asp:TextBox ID ="txt_emp2" runat ="server" ></ asp:TextBox >
< span > 员工3: &nbsp; </ span >< asp:TextBox ID ="txt_emp3" runat ="server" ></ asp:TextBox >
< asp:LinkButton ID ="lbtn_submit" runat ="server" onclick ="lbtn_submit_Click" > 添加 </ asp:LinkButton >
</ div >
</ form >
</ body >
</ html >

//UI/default.aspx.cs

View Code
    
    
    
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
#region 全局变量
BLL.DepartmentBLL db
= new BLL.DepartmentBLL();
#endregion

protected void Page_Load( object sender, EventArgs e)
{
}

protected void lbtn_submit_Click( object sender, EventArgs e)
{
db.AddDepartmentWithSomeEmployees(
this .txt_dep.Text, this .txt_emp1.Text, this .txt_emp2.Text, this .txt_emp3.Text);
}
}

//创建表的Sql命令

View Code
    
    
    
    
create database BLLTransactionDemo
go

use BLLTransactionDemo
go

if exists ( select [ name ] from sysobjects where [ name ] = ' T_Employee ' and [ type ] = ' U ' )
drop table T_Employee
go
create table T_Employee
(
eid
int identity primary key not null ,
ename
nvarchar ( 30 ) not null ,
depid
int
)
go

if exists ( select [ name ] from sysobjects where [ name ] = ' T_Department ' and [ type ] = ' U ' )
drop table T_Department
go
create table T_Department
(
depid
int identity primary key not null ,
depname
nvarchar ( 30 ) not null
)
go

if exists ( select [ name ] from sysobjects where [ name ] = ' SP_AddDepartment ' and [ type ] = ' P ' )
drop procedure SP_AddDepartment
go
create procedure SP_AddDepartment
(
@depname nvarchar ( 30 )
)
as
begin
insert into T_Department(depname) values ( @depname );
return @@identity ;
end
go

exec SP_AddDepartment ' 32 '

if exists ( select [ name ] from sysobjects where [ name ] = ' SP_AddEmployee ' and [ type ] = ' P ' )
drop procedure SP_AddEmployee
go
create procedure SP_AddEmployee
(
@ename nvarchar ( 30 ),
@depid int
)
as
begin
insert into T_Employee(ename,depid) values ( @ename , @depid )
end
go

exec SP_AddEmployee ' ' , 10

select * from T_employee

select * from T_department


2. asp.net的错误处理机制(简述):
asp.net的错误处理机制共分3个层次, 代码级的错误处理, 页面级的错误处理, 网站级的错误处理.

首先, 代码级的错误处理: 很简单,就是try...catch的使用

其次, 页面级的错误处理: 在页面事件处理方法中抛出的异常可以被IHttpHandler中约定的ProcessRequest方法所捕获, 可以通过页面处理对象的Error事件来处理异常.但是Error事件的委托类型是EventHandler, 换句话说就是它无法获得异常信息. 这时, 可以通过HttpContext获得Server对象, 该对象提供了public Exception GetLastError()和pulic void ClearError()两个方法来处理异常. 若,页面级处理了异常, 异常将不再会被抛出到应用程序中.

最后, 网站级的错误处理: 可以在HttpApplication对象的Error事件中处理, 可以再IHttpModule中处理, 但为简单起见, 更常见的是在Global.asax中处理. 值得注意的是, 此时的异常已被包装, 需要通过Server.GetLastException().InnerException来获取异常.
网站级别的异常处理的配置: 当网站出现未处理的异常时, 可以通过web.config文件中的customErrors元素进行配置(mode有3种可选值,off关闭错误处理, 直接显示异常给客户;On想所有用户返回自定义错误信息页面;RemoteOnly向远程用户返回自定义错误信息页面, 向本级客户返回错误详细内容.), 且defaultRedirect属性用来指出自定义的错误信息页面的URL地址(地址可以是相对的, 也可以使绝对的, 相对地址是针对网站根目录的).

你可能感兴趣的:(学习笔记 --- BLL层事物、asp.net异常处理)