事务格式如下:
  1、开启事务: begin tran
  2、提交事务:commit tran
  3、回滚事务:rollback tran
  
  判断事务是提交还是应该回滚有两种方式,一是全局变量 @@error,二是 begin try……end try begin catch……end catch
一、@@error
  @@error作为全局变量,保存着每次执行SQL语句的状态值,当值为0时表示执行正常,否则为错误,因此可以定义一个变量,在每次执行一条SQL语句时都要将该变量的值加上@@error的值,到最后判断该变量值若为0则执行正常可以提交事务,否则回滚。
  我们通过银行转账的例子来看一下 @@error 的用法
  1、创建相关表 Bill

create table Bill
(
ID uniqueidentifier primary key,
name varchar(20),
Balance money
)

2、插入数据并查询数据

insert into Bill values (NEWID(),'小龙',4000),(newid(),'小李',2000)

select * from Bill

如图:

  3、创建存储过程

Create proc Transfer
  @IDFrom uniqueidentifier,@IDTo uniqueidentifier,@Amount money  --参数
as
  declare @errs int =0  --判断出现错误SQL语句的变量,设值为 0
  if (select COUNT(1) from Bill where ID =@IDFrom )>0 and (select COUNT(1) from Bill where ID =@IDTo)>0   --判断转入转出账户是否存在  
      and (select Balance from Bill where ID =@IDFrom)>@Amount+1000  --要求转出账户转出后余额要大于 1000 元
    begin
      begin tran  --开启事务
      update Bill set Balance=Balance -@Amount where ID =@IDFrom
      set @errs =@errs +@@ERROR   --若上一句 update 语句有问题则令 @errs +1 
      update Bill set Balance=Balance +@Amount where ID =@IDTo
      set @errs =@errs +@@ERROR   --若上一句 update 语句有问题则令 @errs +1 
      if @errs =0  --当两条 update 语句无问题时 提交 事务
        begin
          commit tran
          print '转账成功'
        end
      else  --否则 回滚
        rollback tran
    end
  else
    print '转账失败'

:由于全局变量@@ERROR 存储的永远只是上一句SQL语句执行的情况,当执行正常时返回0,否则返回不等于0的值,而再执行一句SQL语句时,执行状态会覆盖上一次的状态吗,因此要用@errs来累计每一句SQL语句的状态值。

    4、执行存储过程,小龙向小李转账 2000

exec Transfer '9FCCA201-8807-4ADA-A482-C63FD8003E54', 'C3A1A21D-3277-4962-AE97-E4C5F8B7F2EB', 2000

     显示转账成功,如图

运行  select * from Bill

如图:

再运行    exec Transfer '9FCCA201-8807-4ADA-A482-C63FD8003E54', 'C3A1A21D-3277-4962-AE97-E4C5F8B7F2EB', 2000

此时由于小龙余额只有2000,达不到要求的转账2000后余额要大于1000的要求,所以转账失败,如图:

二、begin try……end try     begin catch……end catch  方式。

在begin try……end try写事务中的执行代码并在最后提交事务,当执行SQL语句出现问题时,会跳转到  begin catch……end catch 中,因此可以在 begin catch……end catch 中写回滚事务。

  我们以订单号的例子来看一下 begin try……end try 的用法(每次获取最大的号,并+1)

    1、建表并插入数据如下:

create table Orders
(
  name varchar(10),
  OrdersID int,
)
insert into Orders values('订单号',1000)

  2、新建查询,代码如下

  begin tran 
  declare @orderID int
  declare @n int=0
  begin try
    while @n<20  --循环20次
    begin
      select @orderID =max(Orders .OrdersID) from Orders with(xlock,rowlock)
      set @orderID=@orderID +1
      print '链接 1 :'+CONVERT(nvarchar(20),@orderID)
      waitfor delay '00:00:01'
      insert into Orders values('链接 1 ',@orderID) 
      set @n=@n+1
    end
    commit tran
  end try
  begin catch
    rollback tran
  end catch

  select * from Orders

  3、再次新建查询,代码与 2 相似,将'链接 1 '改为'链接 2 ' 代码如下

begin tran 
  declare @orderID int
  declare @n int=0
  begin try
    while @n<20  --循环20次
    begin
      select @orderID =max(Orders .OrdersID) from Orders with(xlock,rowlock)
      set @orderID=@orderID +1
      print '链接 2 :'+CONVERT(nvarchar(20),@orderID)
      waitfor delay '00:00:01'
      insert into Orders values('链接 2 ',@orderID) 
      set @n=@n+1
    end
    commit tran
  end try
  begin catch
    rollback tran
  end catch

  select * from Orders

  4、再次新建查询,将'链接 1 '改为'链接 3 ' 。当然新建查询越多越好,以模拟高并发。并将3个新建查询中代码执行,结果如图,发现号码并没有丢失。

附:锁的兼容性表

现有的授权模式

链接: http://www.cnblogs.com/guanjie20/archive/2013/02/17/2914488.html

SqlServer——事务一编程进阶(SqlServer技术内幕 T-SQL程序设计 第九章的更多相关文章

  1. 《[MySQL技术内幕:SQL编程》读书笔记

    <[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...

  2. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

    原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...

  3. JavaScript DOM编程艺术-学习笔记(第八章、第九章)

    第八章 1.小知识点: ①某些浏览器要根据DOCTYPE 来决定页面的呈现模式(标准模式 / 怪异模式--也称兼容模式): 兼容模式意味着浏览器要模仿老一辈的浏览器的怪异行为,来让老站点得到运行,并让 ...

  4. SqlServer——事务一进阶之锁的概念(SqlServer技术内幕 T-SQL程序设计 第九章)

         一.事务的概念及ACID特性 对于单独一条SQL语句,数据库会隐式的将其作为事务,即该SQL语句要么执行成功,要么失败(相当于不执行),而我们通常说的事务就是将多条SQL语句放在 begin ...

  5. MySQL技术内幕:SQL编程 第2章 数据类型 读书笔记

    2.1 类型属性 2.1.1 UNSIGNED 数字无符号化, INT的值 -2147483648 ~ 2147483647  INT UNSIGNED的值 0 ~ 4294967295 int a ...

  6. 《Spring技术内幕》笔记-第四章 Spring MVC与web环境

    ​上下文在web容器中的启动 1,IoC容器的启动过程 IoC的启动过程就是建立上下文的过程.该上下文是与ServletContext相伴.在Spring中存在一个核心控制分发器,Dispatcher ...

  7. 《java编程思想》P160-P180(第八章部分+第九章部分)

    1.什么是多态? 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行为方式.(发送消息就是函数调用) 现实中,关于多态的例子不胜枚举.比方说按下 F1 ...

  8. 元类理解与元类编程 《Python3网络爬虫开发》中第九章代理的使用代码Crawler中代码的理解

    __new__与__init__的理解 __new__()方法是在创建实例之前被调用的,它的作用是创建一个实例,然后返回该实例对象,它是一个静态方法. __init__() 当实例被创建完成之后被调用 ...

  9. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

随机推荐

  1. this关键字详解

    在java中,编译器会为每个对象分配一个this关键字.在代码中使用关键字可以使代码更优雅.下面我就列举一下this关键字常见的几种场景. 1.this代表当前对象调用成员变量和方法,也是用的最多的地 ...

  2. Codeforces Round #280 (Div. 2) A , B , C

    A. Vanya and Cubes time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  3. js外观模式

    外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式类图: 然而对于外观模式而言,是没有一个一般化的类图描述,下面演示一个外观模式的 ...

  4. LVM MBR分区(装载)

    必须有至少一个主分区(P),主分区个数+扩展分区个数<= 4个. 创建完主分区,可以创建扩展分区(E),扩展分区可以有1个,或者没有(扩展分区). 主分区(Primary  Partion)可以 ...

  5. 第二次ScrumMeeting

    每个人的工作(有Issue的内容和链接):昨天已完成的工作,今天计划完成的工作:工作中遇到的困难. 团队成员 昨日完成任务 明日要完成的任务 易子沐 前端框架学习 issue16 搭建主页框架 iss ...

  6. GEF入门实例_总结_04_Eclipse插件启动流程分析

    一.前言 本文承接上一节:GEF入门实例_总结_03_显示菜单和工具栏 注意到app目录下的6个类文件. 这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们 ...

  7. Angular 4.0 架构详解

    Angular 4.0 架构 这个架构图展现了 Angular 应用中的 8 个主要构造块: 模块 (module) 组件 (component) 模板 (template) 元数据 (metadat ...

  8. python_函数中使用*和**

    Python在函数中,使用*接收元组,使用**接收键/值对 当要使函数接收元组或字典形式的参数 的时候,有一种特殊的方法,它分别使用*和**前缀 .这种方法在函数需要获取可变数量的参数 的时候特别有用 ...

  9. hdu 1671 Phone List (Trie树)

    简单的字典树应用,在建树的时候判断就行了. 需要注意的语法: 在使用malloc和free来处理动态内存的时候,仅仅是释放了这个对象所占的内存,而不会调用这个对象的析构函数:使用new和delete就 ...

  10. Dungeon Master (BFS与DFS的应用)

    个人心得:一开始用DFS弄了半天一直输出不了结果,后面发现并没有进行判断:好不容易能够得出答案,结果超时了,才发现原来要用BFS: 对于DFS: 从一个点开始模拟能走的所有步骤,注意边界条件,走到不能 ...