很多数据库操作需要进行事务,asp.net下面进行事务大致有3个层次:
(1)存储过程层次的事务
(2)ado.net层次的事务
(3)asp.net页面层次的事务
下面分别举例:
首先建立trantest表,字段id(int),test(char)
为id设置主键(利用主键是不允许重复的特性进行事务测试)
(1)
create procedure tran1
as
begin tran
insert into trantest (id,test)values(1,'test')
insert into trantest (id,test)values(1,'test')
if(@@error=0)
commit tran
else
rollback tran
go
运行这个存储过程可以发现一条记录都没有,说明的确是回滚了
清空数据库的记录,修改一下这个存储过程
create procedure tran1
as
begin tran
insert into trantest (id,test)values(1,'test')
insert into trantest (id,test)values(2,'test')
if(@@error=0)
commit tran
else
rollback tran
go
运行这个存储过程可以发现添加了2条记录,说明的确是提交了事务
清空数据库的记录
(2)
sqlconnection conn=new sqlconnection(system.configuration.configurationsettings.appsettings["conn"]);
sqlcommand cmd1=new sqlcommand("insert into trantest (id,test)values(1,'test')",conn);
sqlcommand cmd2=new sqlcommand("insert into trantest (id,test)values(1,'test')",conn);
conn.open();
sqltransaction tran=conn.begintransaction();
cmd1.transaction=tran;
cmd2.transaction=tran;
try
{
cmd1.executenonquery();
cmd2.executenonquery();
tran.commit();
}
catch(sqlexception except)
{
tran.rollback();
response.write(except.message);
}
finally
{
conn.close();
}
同样运行的结果是什么记录都没有添加,清空后再修改为
sqlcommand cmd1=new sqlcommand("insert into trantest (id,test)values(1,'test')",conn);
sqlcommand cmd2=new sqlcommand("insert into trantest (id,test)values(2,'test')",conn);
运行后数据库内有2条记录
(3)
添加引用system.enterpriseservices.dll
using system.enterpriseservices;
serviceconfig config = new serviceconfig();
config.transaction = transactionoption.required;
servicedomain.enter(config);
try
{
work1();
work2();
contextutil.setcomplete();
}
catch(system.exception except)
{
contextutil.setabort();
response.write(except.message);
}
finally
{
servicedomain.leave();
}
然后在页面中添加2个操作,模拟一下在逻辑层调用不同类中的操作的情况
private void work1()
{
sqlconnection conn=new sqlconnection(system.configuration.configurationsettings.appsettings["conn"]);
sqlcommand cmd1=new sqlcommand("insert into trantest (id,test)values(1,'test')",conn);
conn.open();
cmd1.executenonquery();
conn.close();
}
private void work2()
{
sqlconnection conn=new sqlconnection(system.configuration.configurationsettings.appsettings["conn"]);
sqlcommand cmd2=new sqlcommand("insert into trantest (id,test)values(1,'test')",conn);
conn.open();
cmd2.executenonquery();
conn.close();
}
清空数据库后运行后发现的确是没有写入任何记录,再次清空数据库,修改一下work2()
sqlcommand cmd2=new sqlcommand("insert into trantest (id,test)values(2,'test')",conn);运行后发现添加了2条记录。
说明2点:
1、
serviceconfig config = new serviceconfig();
config.transaction = transactionoption.required;
servicedomain.enter(config);
到最后的servicedomain.leave(); 表示
在这段中进行了事务,如果要简单的为整个页面进行事务,修改如下
try
{
work1();
work2();
contextutil.setcomplete();
}
catch(system.exception except)
{
contextutil.setabort();
response.write(except.message);
}
这样就可以了,还有别忘记在前台的page中加上
transaction="required"
2、不要在work1()、work2()中再添加try{}catch{}代码块了
3、因为我的机器是xp sp2,没有注意到这个问题,经思归大哥提醒,恍然大悟,补充一点,有平台限制,只能在windos2003或者xp xp2中运用,否则会给出"当前平台上不支持“serviceconfig”的异常信息,等有机会自己再测试一下。要在xp sp1中使用可以下载补丁,参考:
http://www.alexthissen.nl/weblog/permalink.aspx?guid=f6d61461-d336-40b0-9f4d-51eab6650f27
http://www.rm.com/support/generaldownload.asp?cref=dwn222592&nav=0