关系数据库SQL之可编程性事务
前言
前面关系数据库SQL之可编程性函数(用户自定义函数)一文提到关系型数据库提供了可编程性的函数、存储过程、事务、触发器及游标,前文已介绍了函数、存储过程,本文来介绍一下事务的使用。(还是以前面的银行系统为例)

概述
是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)特性。
语法
开始事务:事务开始的位置,就是单个逻辑工作单元的开始。
回滚事务:就是将数据恢复至事务开始的状态,一般是不满足条件或者是发生错误的时候执行该操作。
提交事务:事务结束的位置,就是单个逻辑工作单元成功执行后,改变数据状态。
--开始事务
BEGIN TRAN[SACTION]
--回滚事务,TRAN[SACTION]可省略
ROLLBACK TRAN[SACTION]
--提交事务
COMMIT TRAN[SACTION]
--事务使用
BEGIN TRAN[SACTION]
--这里是SQL语句块
上面的SQL语句块,需要在适当的位置加上COMMIT TRAN[SACTION],如果需要回滚可以有ROLLBACK TRAN[SACTION]。
事务可以与存储过程联合使用。
特性
- 原子性(Atomic)(Atomicity)
事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。
- 一致性(Consistent)(Consistency)
事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序已强制所有已知的完整性约束。例如,当开发用于转帐的应用程序时,应避免在转帐过程中任意移动小数点。
- 隔离性(Insulation)(Isolation)
由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为隔离性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。当事务可序列化时将获得最高的隔离级别。在此级别上,从一组可并行执行的事务获得的结果与通过连续运行每个事务所获得的结果相同。由于高度隔离会限制可并行执行的事务数,所以一些应用程序降低隔离级别以换取更大的吞吐量。
- 持久性(Duration)(Durability)
事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
示例
- 创建一个带事务的存储过程:孙悟空要取钱,交易信息表里面插入交易信息,同时要更改账户表里面的余额
begin transaction
if exists(select * from sysobjects where name = 'proc_getMoney')
drop procedure proc_getMoney
go
create proc proc_getMoney
@cardId varchar(19),
@tranMoney money
as
declare @balance money
select @balance = LeftMoney from CardInfo where CardID = @cardId
if(@tranMoney <= @balance)
begin
insert into TransInfo values(@cardId,'取款',@tranMoney,default)
if(@@ERROR=0)
begin
update CardInfo set LeftMoney = LeftMoney - @tranMoney where CardID = @cardId
if(@@ERROR=0)
begin
commit transaction
print 'OK'
end
end
else
begin
rollback
print 'error'
end
end
else
print '余额不足'
go
exec proc_getMoney '1324 3626 7532 1935',520
go
exec proc_getMoney '1027 3526 1536 1135',520
go
- 在存储过程内创建事务,根据用户输入的个人信息,实现银行卡开户,输出参数作为用户的银行卡卡号以及银行卡余额(开户时不仅要在用户信息表和银行卡表添加一条数据,也要在交易信息表中插入一条存款的记录,因为开卡时需要指定开卡金额,银行卡卡号自动生成)
if exists(select * from sysobjects where name = 'proc_openAccount')
drop procedure proc_openAccount
go
create proc proc_openAccount
@CustName varchar(20), --定义变量开户人姓名
@IDCard varchar(18), --定义变量开户人身份证号
@TelePhone varchar(13), --定义变量开户人电话号码
@Address varchar(50), --定义变量开户人住址
@openMoney money --定义变量开户存入现金金额
as
begin
begin transaction
declare @CustID int,@CardID varchar(19) --定义变量开户人的账户编号,开户的卡号
exec proc_getCardNo @CardID output --执行自动生成卡号的存储过程,将输出值赋给变量@CardID
--向账户表中插入数据
insert into AccountInfo values
(@CustName,@IDCard,@TelePhone,@Address)
if(@@error != 0)--如果出错
rollback--事务回滚
else
begin
set @CustID = @@identity --获取生成账户的编号CustID
--向银行卡表中插入数据
insert into CardInfo values
(@CardID,default,@CustID,'活期',getdate(),@openMoney,@openMoney,'否')
if(@@error != 0)
rollback
else
begin
--向交易表中插入数据
insert into TransInfo values
(@CardID,'存款',@openMoney,default)
if(@@error != 0)
begin
rollback
print '开户失败,插入数据错误!'
end
else
begin
print '开户成功!'
print '卡号为:' + @CardID
end
end
end
commit transaction
end
go
exec proc_openAccount '八戒','422322001550135015','027-8658888','高老庄',250
go
附:
实现生产银行卡的存储过程,该存储过程能随机的产生一个卡号输出
if exists(select * from sysobjects where name = 'proc_getCardNo')
drop procedure proc_getCardNo
go
create proc proc_getCardNo
@CardNo varchar(19) output --定义输出参数的类型
as
begin
declare @day varchar(2) --定义日期
set @day = dateName(dd,getdate())
if @day<10 --如果日期小于10,要对其加'0'
set @day = '0'+@day
set @CardNo = convert(varchar(9),(dateName(yyyy,getdate())+' '
+ dateName(mm,getdate())))+@day+' '+ convert(varchar(10),(dateName(hh,getdate())
+dateName(mi,getdate())+' '+ subString(convert(varchar(6),rand(datepart(ms,getdate()))*1000000),1,5)))
end
go
declare @card varchar(19)
exec proc_getCardNo @card output
print '卡号为:' + @card
go
本文就介绍到这里。
如有疑问请联系我。
原文来自:简书
关系数据库SQL之可编程性事务的更多相关文章
- 关系数据库SQL之可编程性触发器
前言 前面关系数据库SQL之可编程性函数(用户自定义函数)一文提到关系型数据库提供了可编程性的函数.存储过程.事务.触发器及游标,前文已介绍了函数.存储过程.事务,本文来介绍一下触发器的使用.(还是以 ...
- 关系数据库SQL之可编程性存储过程
前言 前面关系数据库SQL之可编程性函数(用户自定义函数)一文提到关系型数据库提供了可编程性的函数.存储过程.事务.触发器及游标,前文已介绍了函数,本文来介绍一下存储过程的创建.执行.删除.(还是以前 ...
- 关系数据库SQL之可编程性函数(用户自定义函数)
前言 在关系型数据库中除了前面几篇基本的数据库和数据表操作之外,还提供了可编程性的函数.存储过程.事务.触发器及游标. 本文介绍的是函数. 函数分为两种: 系统函数 用户自定义函数 准备工作 这里以银 ...
- Spring(十四)之编程性事务(续)
Spring 编程式事务管理 编程式事务管理方法允许你在对你的源代码编程的帮助下管理事务.这给了你极大地灵活性,但是它很难维护. 在我们开始之前,至少要有两个数据库表,在事务的帮助下我们可以执行多种 ...
- SQL Server 2008空间数据应用系列六:基于SQLCRL的空间数据可编程性
原文:SQL Server 2008空间数据应用系列六:基于SQLCRL的空间数据可编程性 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 ...
- BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。面向切面 将声明性事务管理集成到应用程序中
Spring 系列: Spring 框架简介 https://www.ibm.com/developerworks/cn/java/wa-spring1/ Spring 框架简介 Spring AOP ...
- 走向面试之数据库基础:三、SQL进阶之变量、事务、存储过程与触发器
一.变量那点事儿 1.1 局部变量 (1)声明局部变量 DECLARE @变量名 数据类型 ) DECLARE @id int (2)为变量赋值 SET @变量名 =值 --set用于普通的赋值 SE ...
- SQL入门经典(十) 之事务
事务是什么?事务关键在与其原子性.原子性概念是指可以把一些事情当作一个执行单元来看待.从数据库角度看待.他是指应该全部执行或者全部不执行一条或多条语句的最小组合.当处理数据时候经常确保一件事发生另一件 ...
- 转:SQL进阶之变量、事务、存储过程与触发器
一.变量那点事儿 1.1 局部变量 (1)声明局部变量 DECLARE @变量名 数据类型 DECLARE @name varchar(20) DECLARE @id int (2)为变量赋值 SET ...
随机推荐
- html5学习笔记一
HTML5学习笔记 <video>标记:定义视频,Ogg.MPEG4.WebM三种格式 <video src=”movie.ogg” controls=”controls”> ...
- F.I.S初探(前端工程化)
云笔记:http://note.youdao.com/share/?id=7c4a2dcf118f0ad7bb52a36aaee46a7a&type=note 一.初识FIS 在做项目中遇 ...
- .NET Fringe 定义未来
在dotnetconf 2015会宣布了4.12-14 在波特兰召开 .NET Fringe http://dotnetfringe.org/ ,中文社区很少有相关的介绍,本文向大家介绍下这个.NET ...
- 初识Opserver,StackExchange的监控解决方案
Opserver是闻名遐迩的网站Stack Overflow的开源监控解决方案,由Stack Exchange发布.它基于.NET框架构建,这在监控工具领域有些与众不同. 旨在为每个受监控系统的健康状 ...
- 优秀网站看前端 —— 小米Note介绍页面
刚开始经营博客的时候,我写过不少“扒皮”系列的文章,主要介绍一些知名站点上有趣的交互效果,然后试着实现它们.后来开始把注意力挪到一些新颖的前端技术上,“扒皮”系列便因此封笔多时.今天打算重开“扒皮”的 ...
- [ASP.NET MVC 小牛之路]02 - C#知识点提要
本人博客已转移至:http://www.exblr.com/liam 本篇博文主要对asp.net mvc开发需要撑握的C#语言知识点进行简单回顾,尤其是C# 3.0才有的一些C#语言特性.对于正在 ...
- RabbitMQ Exchange & Queue Design Trade-off
In previous post, I mentioned the discussion on StackOverflow regarding designing exchanges. Usually ...
- 简单了解JS 中的indexOf方法
indexOf() 方法返回指定值在字符串对象中首次出现的位置.从 fromIndex 位置开始查找,如果不存在,则返回 -1. 首先先看下MDN下的参考文档,文档里列出的很详细,这里我只列出了注意点 ...
- 2013 duilib入门简明教程 -- 复杂控件介绍 (13)
首先将本节要介绍的控件全部拖到界面上,并调整好位置,如图: 然后将Name属性改成其他名字, 不能是[控件名+UI+数字]这种,因为这是DuiDesigner ...
- 人之初,性本动 - G2 2.1 发布
前言 随着可视化进入深水区,G2面临了越来越多交互上的需求.动画是提升交互必不可少的一部分,也是之前G2的薄弱环节.这个版本里我们开发并替换了动画底层,统一了时间轴,使G2的动画性能大大提升,并提供了 ...