Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

学习笔记 --- 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地址(地址可以是相对的, 也可以使绝对的, 相对地址是针对网站根目录的).

posted on 2011-04-04 02:46  RJ  阅读(1803)  评论(1编辑  收藏  举报

导航