故如虹,知恩;故如月,知明
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
欢迎加群交流技术

sqlserver事务

4415人阅读 2020/5/21 17:20 总访问:3842293 评论:0 收藏:0 手机
分类: 数据库

事务:把所有的操作当中一个整体,要么全部成功,要么全部失败

      一旦开启了事务所有的操作都是临时的,你可以选择提交或者回滚

      提交事务:全部成功

      回滚事务:全部失败


事务特性(ACID):

事务具有原子性,一致性,隔离性,持久性(ACID)


A 原子性:事务必须是一个自动工作的单元,要么全部执行,要么全部不执行。

C 一致性:事务把数据库从一个一致状态带入到另一个一致状态,事务结束的时候,所有的内部数据都是正确的。

I 隔离性:并发多个事务时,一个事务的执行不受其他事务的影响。

D 持久性:事务提交之后,数据是永久性的,不可再回滚,不受关机等事件的影响。


事务的步骤:


   1:开启事务  begin       trans/transaction      事务名称

   2:提交事务  commit      trans/transaction      事务名称

   3: 回滚事务  rollback    trans/transaction   事务名称


   出现异常事务会自动回滚



来简单模拟一个银行转账的例子:

测试表:

  create Table Account
  (
    Id int primary key identity(1,1),
    MyMoney int,
    AccountNumber nvarchar(64) 
  )
  
  select *from Account
  
  insert Account values(1000,'60023')  
  insert Account values(1000,'60025')
  
  update Account set MyMoney =1000



方法1:

alter proc proc_transmoney(@myAccountNumber nvarchar(64),@outAccountNumber nvarchar(64),@money int)
as
begin
  begin tran trans_money
  
    begin try 
      
      if(@money=0)
      begin
        print('转账金额必须大于0')     
        commit tran trans_money
        return 
      end
      
      
      --验证转入账号是否存在
      declare @count int 
      select @count = COUNT(*) from Account where AccountNumber = @myAccountNumber 
      if(@count=0)
      begin
        print('你的账号输入错误,转账失败')     
        --提交事务(只是为了事务完整)
        commit tran trans_money
        return 
      end
          
      select @count = COUNT(*) from Account where AccountNumber = @outAccountNumber 
      if(@count=0)
      begin
        print('对方账号输入错误,转账失败')     
        --提交事务(只是为了事务完整)
        commit tran trans_money
        return 
      end
      
      --验证余额
      declare @lastMoney int
      select @lastMoney = MyMoney from Account where AccountNumber = @myAccountNumber 
      if(@money>@lastMoney)
      begin
         print('你的余额不足,转账失败。你的余额为:'+cast(@lastMoney as varchar))     
        commit tran trans_money
        return 
      end
      
         
    
      update Account set MyMoney = MyMoney-@money where AccountNumber = @myAccountNumber   
      update Account set MyMoney = MyMoney+@money where AccountNumber =@outAccountNumber 
      commit tran trans_money 
      print('转账成功')
    end try
    
    --当异常出现的时候会执行
    begin catch
       print('转账出现错误,转账失败')
       --回滚事务
       rollback tran trans_money
    end catch 
end

方法2:

alter proc proc_transmoney(@myAccountNumber nvarchar(64),@outAccountNumber nvarchar(64),@money int,@num1 nvarchar(64) out)
as
begin
  begin tran trans_money
  
    begin try 
      
      if(@money=0)
      begin
        print('转账金额必须大于0')     
        commit tran trans_money
        return 
      end
          
      --验证转入账号是否存在
      declare @count int 
         
      --验证余额
      declare @lastMoney int
      select @lastMoney = MyMoney from Account where AccountNumber = @myAccountNumber 
      if(@money>@lastMoney)
      begin
      
        set @num1=('你的余额不足,转账失败。你的余额为:'+cast(@lastMoney as varchar))     
        commit tran trans_money
        return 
      end
              
      update Account set MyMoney = MyMoney-@money where AccountNumber = @myAccountNumber   
      if(@@ROWCOUNT=0)
      begin
        set @num1=('你的账号输入错误,转账失败')     
        rollback tran trans_money
        return 
      end
           
      update Account set MyMoney = MyMoney+@money where AccountNumber =@outAccountNumber 
      
      if(@@ROWCOUNT=0)
      begin
        set @num1=('对方的账号输入错误,转账失败')     
        rollback tran trans_money
        return 
      end
      
      commit tran trans_money 
     set @num1=('转账成功')
    end try
    
    --当异常出现的时候会执行
    begin catch
       set @num1=('转账出现错误,转账失败')
       --回滚事务
       rollback tran trans_money
    end catch 
end

c#执行这个存储过程,这里就简单的直接执行的

static void Main(string[] args)
        {
            SqlConnection conn = new SqlConnection("server=.;uid=sa;pwd=123456;database=oa");
            conn.Open();

            SqlCommand com = new SqlCommand();
            //给命令指定一个连接对象
            com.Connection = conn;

            //设置命令的类型为存储过程
            com.CommandType = System.Data.CommandType.StoredProcedure;
            //指定存储过程的名字
            com.CommandText = "proc_transmoney";

            Console.WriteLine("请输入你的账号");
            string myAccount = Console.ReadLine();

            //你的账号
            SqlParameter myAccountNumber = new SqlParameter("myAccountNumber", myAccount);
            com.Parameters.Add(myAccountNumber);

            Console.WriteLine("请输入对方的账号");
            string outAccount = Console.ReadLine();

            //对方的账号
            com.Parameters.AddWithValue("outAccountNumber", outAccount);
            //转账的金额
            Console.WriteLine("请输入转账的金额");
            string myMoney = Console.ReadLine();
            com.Parameters.AddWithValue("money", myMoney);

 
            
            SqlParameter sqlParameter = new SqlParameter();
            //参数类型
            sqlParameter.SqlDbType = System.Data.SqlDbType.NVarChar;

            //指定参数大小
            sqlParameter.Size = 256;

            //参数方向,输出还是输入
            sqlParameter.Direction = System.Data.ParameterDirection.Output;

            sqlParameter.ParameterName = "num1";

            com.Parameters.Add(sqlParameter);

            //执行
            com.ExecuteReader();
            Console.WriteLine(sqlParameter.Value);
        }


欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739

评价