事务将控制和维护数据库的一致性和完整性(出错不会对数据库作修改)。应用中包含的事务应当尽量让它“瞬间”完成,避免在比较忙时造成用户进程的互锁。
事务处理过程:
A。事务待命:开始一个事务
B。事务日志:记录事务中改变的数据记录。不直接改变数据库中的值,而是用一个顺序的“事务日志”记录在一边。同时,对于要改变的原始记录加锁,让其它用户无法读和写。如果记录已经被其它事务加锁,则报错。
C。事务拷贝:Commit Transaction,拷贝所有加锁的记录成备份。
D。事务更新:用“事务日志”中的记录一一更新实际的数据库记录。
E。事务结束:释放所有的记录锁,然后抛弃“事务日志”和备分的原数据库记录。完成之些工作后,事务被删除。
事务处理的方法:
A。直接写SQL:在存储过程中使用begin tran,commit tran,rollback tran实现。
优点:所有事务逻辑包含在一个单独的调用中;拥有运行一个事务的最佳性能;独立于应用程序
限制:事务上下文仅存在于数据库调用中(即事务的SQL对外不能访问,只能调用存储过程);数据库代码与数据库系统有关(不同数据库写法不一样)。
B。通过ADO.NET实现:调用Connection对象的Transaction方法。
SqlTransaction Trans = Conn.BeginTransaction(); //SqlConnection
Cmd.Transaction = Trans; //SlqCommand
try { ... Trans.Commit(); ...}
catch(Exception Exp) {... Trans.Rollback(); ...}
finally { Conn.Close(); }
优点:简单;和数据库事务速度相近;独立于数据库,不同数据库的专有代码被隐藏。
缺点:事务不能跨越多个数据库连接;事务执行在数据库连接层上,所以需要在事务过程中维护一个数据库连接。
C。COM+事务(可以利用COM+来完成在分布式应用程序中的事务控制)
在分布式应用程序中,我们经常需要同时操作多个数据库,使用数据库本身的事务处理很难满足程序对事务控制的要求(一般事务的操作必须在同一个数据库内)。
为使该组件正确运行,该组件必须有一个强名称。生成一个强名称,然后使用该强名称对程序集进行签名。步骤如下(不懂,原文照搬):
1。将TransactionAttribute类应用于您的类,指定组件请求的自动事务类型。事务类型必须是TransactionOption枚举的成员。
2。从Servicedcomponent类派生您的类。ServicedComponent是所有使用COM+服务的类的基类。
3。用强名称(strong name)标记(sign)程序集(assembly),确保程序集包含唯一的密钥对。
4。在COM+ catalog中注册包含您的类的程序集。
COM+事务实例:
A。右键解决方案,添加类库,名称为COM,新建EnterpriseCls类如下。
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.EnterpriseServices;
namespace COM
{
[Transaction(TransactionOption.Required)]
/**//*
* TransactionOption枚举类型支持5个COM+值
* -Disabled 忽略当前上下文中的任何事务
* -NotSupported 使用非受控事务在上下文中创建组件
* -Required 如果事务存在共享事务,并且如有必要则创建新事务
* -RequrisNew 使用新事务创建组件,而与当前上下文的状态无关
* -Supported 如果事务存在,则共享该事务
*/
public class EnterpriseCls : ServicedComponent
{
public void UpdateData(int ParamId)
{
try
{
SqlConnection Conn = new SqlConnection("");
Conn.Open();
SqlCommand Cmd = new SqlCommand("Update ", Conn);
Cmd.ExecuteNonQuery();
ContextUtil.SetComplete();
Conn.Close();
}
catch (Exception Exp)
{
ContextUtil.SetAbort();
throw Exp;
}
finally { }
}
}
}
B。项目中添加类库的COM.dll。使用EnterpriseCls类实例化对象时报错:在程序集中找到无效的ServicedComponent派生类。
C。打开COM类库的Properties下的AssemblyInfo.cs,把[assembly: ComVisible(false)]中的false改成true。
D。运行项目,再次报错:程序集XXX没有强名称。
注:以下做法为本人归结,与邵老师的视频不符,如有错误,希望高人指出。
E。把类库的COM.dll复制到C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0下。打开SDK命令提示(所有程序-Microsoft .NET Framework SDK v2.0。默认路径:C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0),输入以下命令:
1。sn -k com.snk //创建一个密钥
2。ildasm com.dll /out=com.il //反编译目标程序集
3。ilasm com.il /dll /resource=com.res /key=com.snk //重新编译,附带强命名参数
4。sn -v com.dll //验证签名信息
F。把项目中原来的com.dll引用去掉,把生成的com.dll(sdk文件夹中)重新引入到项目中。编译,运行,通过。
异常处理:可以使用checked或try...catch...finally语句。
异常优化:确保所有程序的入口都使用了try-catch,在catch中截获所有的异常。
异常注意事项:
A。当引发异常时,要提供有意义的文本。
B。要引发异常仅当条件是真正异常;也就是当一个正常的返回值不满足时。
C。如果你的方法或属性被传递一个坏参数,要引发一个ArgumentException异常。
D。当调用操作不适合对象的当前状态时,要引发一个InvalidOperationException异常。
E。要引发最适合的异常。
F。不要为正常或要预期的错误使用异常。
G。不要为流程的正常控制使用异常。
H。不要在方法中引发NullReferenceException或IndexOutOfRangeException异常。
异常处理技术:
A。记录异常
1。在文件中记录异常
2。在数据库中记录异常
3。在eventlog中记录异常
B。发送email通知异常
C。异常产生时,用友好的方式通知用户
处理错误:
A。Page_Error事件
B。Application_Error事件
C。自定义错误页面<customError节点>3