标签:撤销 arch 序列 strong 操作 语句 解决 示例 一个
简介
事务是单个的工作单元,这就意味着单元内有多个操作,事务是多个操作的整合体。如果某个事务执行成功,则涵盖在这个事务里的所有数据操作均会一并执行提交,成为数据库中的永久组成部分。
如果事务因某项操作执行错误,那么事务内所有的操作都将无效,事务实行回滚机制,数据操作都会还原到初始为更改的状态。
为什么需要事务
在银行业务中,有一条记账原则,即有借有贷,借贷相等。为了保证这种原则,每发生一笔银行业务,就必须确保账目上借方和贷方至少个记一笔账,并且这两笔账要么同时成功,要么同时失败。
如果账目上的记录只出现了借方,或者只出现了贷方。那么这就违反了记账的原则,出现记账错误的情况。此业务场景就是事务典型的体现,通过事务处理的处理机制,才可以解决此类业务场景。
示例分析
业务场景:
银行转账往往涉及两个或两个以上的账户,包括转出对象和转入对象两种。在转出的存款金额减少一定金额的同时,转入账户会增加相应金额的存款。接下来以转账的场景为例,用代码演示转账的过程。
数据准备:
--创建表
if exists(select * from sysobjects where name=‘bank‘ )
drop table bank
go
create table bank
(
customerName nvarchar(4),
currentMoney money
)
go
--添加约束:账户余额(currentMoney)不能少于1元,否则视为销户
alter table bank
add constraint ck_currentMoney check (currentMoney>=1)
go
--插入测试数据,即转账的两个对象:张三账户余额为1000元,李四账户余额为1元
insert into bank values (‘张三‘,1000),(‘李四‘,1);
go
--查看结果
select * from bank go
使用SQL语句模拟转账功能:
逻辑:从张三的账户直接转账1000元到李四的账户,张三账户减少1000元。李四账户增加1000元。
代码如下:
--根据业务逻辑编写SQL语句执行数据操作
--转出
update bank set currentMoney=currentMoney-1000
where customerName=‘张三‘
--转入
update bank set currentMoney=currentMoney+1000
where customerName=‘李四‘
执行结果:
结果分析:
张三转给李四的1000元并没有从账户里扣除,李四的账户却多了1000元,转账后两个账户的余额总和变为1000+1001=2001,存入银行的钱凭空多出1000元。如果此操作发生在生活中,想一想是多么可怕的事情。此操作的原因是因为之前在创建表的时候定义的约束,导致第一个SQL命令无法执行,下一个SQL没有因为中断停止执行。
如果在程序中,可能会用代码逻辑去控制,即等第一个命令执行成功在执行下一个命令,这样虽然可以监控第一个命令的结果做出对应的处理。但是如果第一个命令执行成功,第二个命令执行出错该怎么办,这样还是无法确保一个业务的整体性。
我们可以使用事务机制来解决此问题,转账过程就是一个事务,它需要两条或者更多条SQL语句来完成一系列的操作,不管有多少条命令,它们始终围绕着一个主题就是转账。如果其中某个步骤出错,则整个转账业务也不能成立,应出错要把事务中操作的数据恢复为原来的数据。在开发中如果不使用事务处理机制,我们是很难保证事务中单个操作不出错的。一旦事务中某个操作出错就导致了整体的逻辑性。
事务的概念
事务是一种机制,一个操作序列,它包含了多个操作命令,并且把所有的命令作为一个整体并都围绕着一种业务主题一起向系统提交或撤销操作请求,即这一组命令要么都执行,要么都不执行,通俗的理解就是共同进退。因此事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是作为最小的控制单元来使用的,它特别适用于多用户同时操作的数据库系统。例如,航空公司的订票系统、银行、保险公司等。
事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,即原子性、一致性、隔离性、持久性,这些特性简称为ACID。
标签:撤销 arch 序列 strong 操作 语句 解决 示例 一个
原文地址:https://www.cnblogs.com/green-jcx/p/9306330.html