一、事務(wù)概念
事務(wù)是一種機制、是一種操作序列,它包含了一組數(shù)據(jù)庫操作命令,這組命令要么全部執(zhí)行,要么全部不執(zhí)行。因此事務(wù)是一個不可分割的工作邏輯單元。在數(shù)據(jù)庫系統(tǒng)上執(zhí)行并發(fā)操作時事務(wù)是作為最小的控制單元來使用的。這特別適用于多用戶同時操作的數(shù)據(jù)通信系統(tǒng)。例如:訂票、銀行、保險公司以及證券交易系統(tǒng)等。
二、事務(wù)屬性
事務(wù)4大屬性:
1?? 原子性(Atomicity):事務(wù)是一個完整的操作。
2?? 一致性(Consistency):當(dāng)事務(wù)完成時,數(shù)據(jù)必須處于一致狀態(tài)。
3?? 隔離性(Isolation):對數(shù)據(jù)進行修改的所有并發(fā)事務(wù)是彼此隔離的。
4?? 持久性(Durability):事務(wù)完成后,它對于系統(tǒng)的影響是永久性的。
三、創(chuàng)建事務(wù)
T-SQL中管理事務(wù)的語句:
1 開始事務(wù): begin transaction
2 提交事務(wù):commit transaction
3 回滾事務(wù): rollback transaction
事務(wù)分類:
1 顯式事務(wù):用begin transaction明確指定事務(wù)的開始。
2 隱性事務(wù):打開隱性事務(wù):set implicit_transactions on,當(dāng)以隱性事務(wù)模式操作時,SQL Servler將在提交或回滾事務(wù)后自動啟動新事務(wù)。無法描述事務(wù)的開始,只需要提交或回滾事務(wù)。
3 自動提交事務(wù):SQL Server的默認模式,它將每條單獨的T-SQL語句視為一個事務(wù)。如果成功執(zhí)行,則自動提交,否則回滾。
示例:張三轉(zhuǎn)800元到李四帳戶上。
use stuDB
go
--創(chuàng)建帳戶表bank--
if exists(select* from sysobjects where name='bank')
drop table bank
create table bank
(
customerName char(10),??? --顧客姓名
currentMoney money??????? --當(dāng)前余額
)
go
/**//*--添加約束,帳戶不能少于元--*/
alter table bank add
constraint CK_currentMoney check(currentMoney>=1)
/**//*--插入測試數(shù)據(jù)--*/
insert into bank(customerName,currentMoney)
select '張三',1000 union
select '李四',1
select * from bank
go
/**//*--使用事務(wù)--*/
use stuDB
go
--恢復(fù)原來的數(shù)據(jù)
--update bank set currentMoney=currentMoney-1000 where customerName='李'
set nocount on??? --不顯示受影響的行數(shù)
print '查看轉(zhuǎn)帳事務(wù)前的余額'
select * from bank
go
/**//*--開始事務(wù)--*/
begin transaction
declare @errorSum int??? --定義變量,用于累計事務(wù)執(zhí)行過程中的錯誤
/**//*--轉(zhuǎn)帳--*/
update bank set currentMoney=currentMoney-800 where customerName='張三'
set @errorSum=@errorSum+@@error??? --累計是否有錯誤
update bank set currentMoney=currentMoney+800 where customerName='李四'
set @errorSum=@errorSum+@@error --累計是否有錯誤
print '查看轉(zhuǎn)帳事務(wù)過程中的余額'
select * from bank
/**//*--根據(jù)是否有錯誤,確定事務(wù)是提交還是回滾--*/
if @errorSum>0
begin
print '交易失敗,回滾事務(wù).'
rollback transaction
end
else
begin
print '交易成功,提交事務(wù),寫入硬盤,永久保存!'
commit transaction
end
go
print '查看轉(zhuǎn)帳后的余額'
select * from bank
go
sql事務(wù)(Transaction)用法介紹及回滾實例
事務(wù)(Transaction)是并發(fā)控制的單位,是用戶定義的一個操作序列。這些操作要么都做,要么都不做,是一個不可分割的工作單位。通過事務(wù),SQL Server能將邏輯相關(guān)的一組操作綁定在一起,以便服務(wù)器保持?jǐn)?shù)據(jù)的完整性
當(dāng)對多個表進行更新的時候,某條執(zhí)行失敗。為了保持?jǐn)?shù)據(jù)的完整性,需要使用事務(wù)回滾。
顯示設(shè)置事務(wù)
代碼如下
begin try ? www.2cto.com
begin transaction
insert into shiwu (asd) values ('aasdasda');
commit transaction
end try
begin catch
select ERROR_NUMBER() as errornumber
rollback transaction
end catch
隱式設(shè)置事務(wù)
代碼如下
set implicit_transactions on; -- 啟動隱式事務(wù)
go
begin try
insert into shiwu (asd) values ('aasdasda');
insert into shiwu (asd) values ('aasdasda');
commit transaction;
end try
begin catch
select ERROR_NUMBER() as errornumber
rollback transaction; --回滾事務(wù)
end catch
set implicit_transactions off; --關(guān)閉隱式事務(wù)
go
顯示事務(wù)以下語句不能使用,隱式事務(wù)可以
代碼如下
alter database;
backup; ? www.2cto.com
create database;
drop database;
reconfigure;
restore;
update statistics;
顯示事務(wù)可以嵌套使用
代碼如下
--創(chuàng)建存儲過程
create procedure qiantaoProc
@asd nchar(10)
as
begin
begin try
begin transaction innerTrans
save transaction savepoint --創(chuàng)建事務(wù)保存點
insert into shiwu (asd) values (@asd);
commit transaction innerTrans
end try
begin catch
rollback transaction savepoint --回滾到保存點
commit transaction innerTrans
end catch
end
go
begin transaction outrans
exec qiantaoProc 'asdasd';
rollback transaction outrans
事務(wù)嵌套,回滾外層事務(wù)時,如果嵌套內(nèi)的事務(wù)已經(jīng)回滾過則會有異常。此時需要使用事務(wù)保存點。如下實例
SQL事務(wù)回滾
指定當(dāng) ? Transact-SQL ? 語句產(chǎn)生運行時錯誤時,Microsoft? ? SQL ? Server? ? 是否自動回滾當(dāng)前事務(wù)
方案一:
代碼如下
SET ? XACT_ABORT ? ON--如果產(chǎn)生錯誤自動回滾
GO
BEGIN ? TRAN
INSERT ? INTO ? A ? VALUES ? (4)
INSERT ? INTO ? B ? VALUES ? (5)
COMMIT ? TRAN ?www.2cto.com
也可以使用_ConnectionPtr 對象的方法: BeginTrans、CommitTrans、RollbackTrans,使用該系列函數(shù)判斷并回滾。一旦調(diào)用了 BeginTrans 方法, 在調(diào)用 CommitTrans 或 RollbackTrans 結(jié)束事務(wù)之前,數(shù)據(jù)庫將不再立即提交所作的任何更改。
方案二
代碼如下
BEGIN TRANSACTION
INSERT INTO A ? values ?(4) ? ----- 該表含有觸發(fā)器,UPDATE其他表
IF @@error <> 0 ?--發(fā)生錯誤
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END
sql事務(wù)結(jié)合asp.net兩種用法
在sql server+ .net 開發(fā)環(huán)境下,有兩種方法能夠完成事務(wù)的操作,保持?jǐn)?shù)據(jù)庫的數(shù)據(jù)完整性;一個就是用sqlserver/42850.htm target=_blank >sql存儲過程,另一個就是在ADO.NET中一種簡單的事務(wù)處理;現(xiàn)在通過一個典型的銀行轉(zhuǎn)賬的例子來說明一下這兩個例子的用法我們先來看看sql存儲過程是如何來完成事務(wù)的操作的:首先創(chuàng)建一個表:
代碼如下
create database aaaa --創(chuàng)建一個表,包含用戶的帳號和錢數(shù)gouse aaaacreate table bb( ID int not null primary key, ?--帳號 moneys money ? ?--轉(zhuǎn)賬金額)insert into bb values ('1','2000') --插入兩條數(shù)據(jù)insert into bb values ('2','3000')用這個表創(chuàng)建一個存儲過程:
create procedure mon --創(chuàng)建存儲過程,定義幾個變量
@toID int, ? ?--接收轉(zhuǎn)賬的賬戶
@fromID int , ?--轉(zhuǎn)出自己的賬戶
@momeys money --轉(zhuǎn)賬的金額
as
begin tran --開始執(zhí)行事務(wù)
update bb set moneys=moneys-@momeys where ID=@fromID -執(zhí)行的第一個操作,轉(zhuǎn)賬出錢,減去轉(zhuǎn)出的金額
update bb set moneys=moneys+@momeys where ID=@toID --執(zhí)行第二個操作,接受轉(zhuǎn)賬的金額,增加 ?www.2cto.com
if @@error<>0 --判斷如果兩條語句有任何一條出現(xiàn)錯誤
begin rollback tran –開始執(zhí)行事務(wù)的回滾,恢復(fù)的轉(zhuǎn)賬開始之前狀態(tài)
return 0
end
go
else ? --如何兩條都執(zhí)行成功
begin commit tran 執(zhí)行這個事務(wù)的操作
return 1
end
go
接下來看看C#.net 是如何調(diào)用這個存儲過程的:
代碼如下
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection con =new SqlConnection(@"Data Source=.SQLEXPRESS;database=aaaa;uid=sa;pwd=jcx"); //連接字符串
SqlCommand cmd = new SqlCommand("mon",con); //調(diào)用存儲過程
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
SqlParameter prar = new SqlParameter();//傳遞參數(shù)
cmd.Parameters.AddWithValue("@fromID", 1);
cmd.Parameters.AddWithValue("@toID", 2);
cmd.Parameters.AddWithValue("@momeys",Convert.ToInt32( TextBox1.Text) );
www.2cto.com
cmd.Parameters.Add("@return", "").Direction = ParameterDirection.ReturnValue;//獲取存儲過程的返回值
cmd.ExecuteNonQuery();
string value = cmd.Parameters["@return"].Value.ToString();//把返回值賦值給value
if (value == "1")
{
Label1.Text = "添加成功";
}
else
{
Label1.Text = "添加失敗";
}
}
這個也就是在存儲過程里添加事務(wù),再來看看不在數(shù)據(jù)庫寫sql存儲過程,ADO.NET是如何處理事務(wù)的:
代碼如下
protected void Button2_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(@"Data Source=.SQLEXPRESS;database=aaaa;uid=sa;pwd=jcx");
con.Open();
SqlTransaction tran = con.BeginTransaction();//先實例SqlTransaction類,使用這個事務(wù)使用的是con 這個連接,使用BeginTransaction這個方法來開始執(zhí)行這個事務(wù)
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.Transaction = tran;
try
{
//在try{} 塊里執(zhí)行sqlcommand命令,
cmd.CommandText = "update bb set moneys=moneys-'" + Convert.ToInt32(TextBox1.Text) + "' where ID='1'";
cmd.ExecuteNonQuery();
cmd.CommandText = "update bb set moneys=moneys+' aa ' where ID='2'";
cmd.ExecuteNonQuery();
tran.Commit();//如果兩個sql命令都執(zhí)行成功,則執(zhí)行commit這個方法,執(zhí)行這些操作
www.2cto.com
Label1.Text = "添加成功";
}
catch
{
Label1.Text = "添加失敗";
tran.Rollback();//如何執(zhí)行不成功,發(fā)生異常,則執(zhí)行rollback方法,回滾到事務(wù)操作開始之前;
}
}
這就是兩個事務(wù)不同用法的簡單例子,ADO.NET 事務(wù)處理的方法看起來比較簡單,但是他要使用同一個連接來執(zhí)行這些操作,要是同時使用幾個數(shù)據(jù)庫來用一個事務(wù)執(zhí)行,這樣就比較繁瑣,但是要是用sql存儲過程,這樣就相對比較簡單