SqlServer——事务一编程进阶(SqlServer技术内幕 T-SQL程序设计 第九章
事务格式如下:
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程序设计 第九章的更多相关文章
- 《[MySQL技术内幕:SQL编程》读书笔记
<[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
- JavaScript DOM编程艺术-学习笔记(第八章、第九章)
第八章 1.小知识点: ①某些浏览器要根据DOCTYPE 来决定页面的呈现模式(标准模式 / 怪异模式--也称兼容模式): 兼容模式意味着浏览器要模仿老一辈的浏览器的怪异行为,来让老站点得到运行,并让 ...
- SqlServer——事务一进阶之锁的概念(SqlServer技术内幕 T-SQL程序设计 第九章)
一.事务的概念及ACID特性 对于单独一条SQL语句,数据库会隐式的将其作为事务,即该SQL语句要么执行成功,要么失败(相当于不执行),而我们通常说的事务就是将多条SQL语句放在 begin ...
- MySQL技术内幕:SQL编程 第2章 数据类型 读书笔记
2.1 类型属性 2.1.1 UNSIGNED 数字无符号化, INT的值 -2147483648 ~ 2147483647 INT UNSIGNED的值 0 ~ 4294967295 int a ...
- 《Spring技术内幕》笔记-第四章 Spring MVC与web环境
上下文在web容器中的启动 1,IoC容器的启动过程 IoC的启动过程就是建立上下文的过程.该上下文是与ServletContext相伴.在Spring中存在一个核心控制分发器,Dispatcher ...
- 《java编程思想》P160-P180(第八章部分+第九章部分)
1.什么是多态? 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行为方式.(发送消息就是函数调用) 现实中,关于多态的例子不胜枚举.比方说按下 F1 ...
- 元类理解与元类编程 《Python3网络爬虫开发》中第九章代理的使用代码Crawler中代码的理解
__new__与__init__的理解 __new__()方法是在创建实例之前被调用的,它的作用是创建一个实例,然后返回该实例对象,它是一个静态方法. __init__() 当实例被创建完成之后被调用 ...
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
随机推荐
- 【转】php 操作数组(合并,拆分,追加,查找,删除等)
1. 合并数组 array_merge()函数将数组合并到一起,返回一个联合的数组.所得到的数组以第一个输入数组参数开始,按后面数组参数出现的顺序依次迫加.其形式为: array array_merg ...
- 域名解析中TTL是什么意思
在做域名解析的时候都会看到一个叫“TTL”的值,一般都有一个默认的值,不过不同注册商默认的值也会不一样,常见的是3600和7200这两个值. 另外ping的时候也可以看到“TTL=XXX”的字样,(如 ...
- DanceLink
DanceLink是一个可以解决精确覆盖和重复覆盖的搜索算法 重复覆盖就是在精确覆盖的remove等处做改变 都是十字循环链表 精确覆盖 给出一个01矩阵 要求选择几行 使每一列都有且仅有一个1 在求 ...
- 直播P2P技术1-技术入门
1. 直播协议 直播协议主要有RTMP,HLS,MPEG-DASH,RTSP,HTTP-FLV等.每种协议都各有长短,比如RTMP延迟低,但诞生于Adobe,依赖于Flash Player,在如今FL ...
- js+css实现简单下拉菜单
<head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312&qu ...
- js中scrollIntoView()的用法
一. 什么是scrollIntoView scrollIntoView是一个与页面(容器)滚动相关的API 二. 如何调用 element.scrollIntoView() 参数默认为true 参数为 ...
- Rainmeter如何打开控制面板的小程序
控制面板功能都是通过访问cpl文件来关联它们的,假设你的系统盘在C盘,那么它们的本地在C:\Windows\System32\ Rainmeter通过使用这个应用程序C:\Windows\System ...
- 2018.8.11E-mail
1发送附件 Attached please find the XXX for your review and comment. Outlook的附件最好不超过10M,文件要用英语命名,视频音频要压缩 ...
- 【SQL查询】查询结果分组_Group
1. 概述 “Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组 示例 2. group by的简单操作 3. Group By中Select指定的字段限制 select指定的 ...
- git公私钥的拷贝
1.场景 由于我换了一台电脑,为了能访问远程仓库,我就把原来电脑上的私钥和config文件拷贝过来 2.出现问题及解决方案 git clone server:xxx_service_express 报 ...