一、事务概念
事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。例如:订票、银行、保险公司以及证券交易系统等。
二、事务属性
事务4大属性:
1 原子性(Atomicity):事务是一个完整的操作。
2 一致性(Consistency):当事务完成时,数据必须处于一致状态。
3 隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的。
4 持久性(Durability):事务完成后,它对于系统的影响是永久性的。
三、创建事务
T-SQL中管理事务的语句:
1 开始事务: begin transaction
2 提交事务:commit transaction
3 回滚事务: rollback transaction
事务分类:
1 显式事务:用begin transaction明确指定事务的开始。
2 隐性事务:打开隐性事务:set implicit_transactions on,当以隐性事务模式操作时,SQL Servler将在提交或回滚事务后自动启动新事务。无法描述事务的开始,只需要提交或回滚事务。
3 自动提交事务:SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。
下面的两种事务方法,附上代码
第一种:存储过程
create proc proc_zhuanzhang @toNameID int,--接收转账的账户 @fromNameID int,--转出自己的账户 @momeys int --转账的金额 as begin tran tran_money --开始事务 declare @tran_error int; set @tran_error = 0; begin try update a set [money] = [money]-@momeys where id = @fromNameID; set @tran_error = @tran_error+@@ERROR; --测试出错代码,看看张三的钱减少,李四的钱是否会增加 --set @tran_error = 1; update a set [money] = [money]+@momeys where id = @toNameID; set @tran_error = @tran_error+@@ERROR; end try begin catch PRINT '出现异常,错误编号:' + convert(varchar,error_number()) + ',错误消息:' + error_message() SET @tran_error = @tran_error + 1 end catch IF(@tran_error > 0) BEGIN --执行出错,回滚事务 ROLLBACK TRAN; PRINT '转账失败,取消交易!'; END ELSE BEGIN --没有异常,提交事务 COMMIT TRAN; PRINT '转账成功!'; END
C# 代码调用存储过程
protected void btnzz_Click(object sender, EventArgs e) { SqlConnection conn = new SqlConnection(@"Data Source=.;database=oa2010;uid=sa;pwd=sa"); SqlCommand cmd = new SqlCommand("proc_zhuanzhang",conn); cmd.CommandType = CommandType.StoredProcedure; conn.Open(); SqlParameter prar = new SqlParameter();//传递参数 cmd.Parameters.AddWithValue("@toNameID", 13);//张三 cmd.Parameters.AddWithValue("@fromNameID", 14);//李四 cmd.Parameters.AddWithValue("@momeys", Convert.ToInt32(TextBox1.Text)); cmd.Parameters.Add("@return", "").Direction = ParameterDirection.ReturnValue;//获取存储过程的返回值 cmd.ExecuteNonQuery(); string value = cmd.Parameters["@return"].Value.ToString();//把返回值赋值给value if (value == "0") { Label1.Text = "转账成功"; } else { Label1.Text = "转账失败"; } }
二、第二种方法:ADO.net
protected void Button1_Click(object sender, EventArgs e) { SqlConnection con = new SqlConnection(@"Data Source=.;database=oa2010;uid=sa;pwd=sa"); con.Open(); SqlTransaction tran = con.BeginTransaction();//先实例SqlTransaction类,使用这个事务使用的是con 这个连接,使用BeginTransaction这个方法来开始执行这个事务 SqlCommand cmd = new SqlCommand(); cmd.Connection = con; cmd.Transaction = tran; try { //在try{} 块里执行sqlcommand命令, cmd.CommandText = "update a set money=money-" + Convert.ToInt32(TextBox1.Text) + " where id=13";//张三id cmd.ExecuteNonQuery(); cmd.CommandText = "update a set money=money+"+ Convert.ToInt32(TextBox1.Text) +" where id=14";//李四id cmd.ExecuteNonQuery(); tran.Commit();//如果两个sql命令都执行成功,则执行commit这个方法,执行这些操作 Label1.Text = "添加成功"; } catch { Label1.Text = "添加失败"; tran.Rollback();//如何执行不成功,发生异常,则执行rollback方法,回滚到事务操作开始之前; } }
代码附上:事务两种方法下载