很多數據庫操作需要進行事務,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