From f70e51ce764656e3b5e019d14ab2b74203f2c8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=AF=E9=94=9F=E9=93=96?= <2435175736@qq.com> Date: Mon, 19 Sep 2022 13:24:26 +0000 Subject: [PATCH] =?UTF-8?q?=E5=95=8A=E5=95=8A=E5=95=8A=E5=95=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 侯锟铖 <2435175736@qq.com> --- .../8-9.19\344\272\213\345\212\241.Markdown" | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 "17 \344\276\257\351\224\237\351\223\226/\347\254\224\350\256\260/8-9.19\344\272\213\345\212\241.Markdown" diff --git "a/17 \344\276\257\351\224\237\351\223\226/\347\254\224\350\256\260/8-9.19\344\272\213\345\212\241.Markdown" "b/17 \344\276\257\351\224\237\351\223\226/\347\254\224\350\256\260/8-9.19\344\272\213\345\212\241.Markdown" new file mode 100644 index 0000000..9ef3164 --- /dev/null +++ "b/17 \344\276\257\351\224\237\351\223\226/\347\254\224\350\256\260/8-9.19\344\272\213\345\212\241.Markdown" @@ -0,0 +1,88 @@ +# 事务 +## 一、什么是事务 + + 事务是在数据库上按照一定的逻辑顺序执行的任务序列,是恢复和控制并发的基本单位,既可以由用户手动执行,也可以由某种数据库程序自动执行。 + +## 二、事务的属性 +一般来说,事务具有四个标准属性,分别是原子性(或称不可分割性)、一致性、隔离性(又称独立性)、持久性。具体说明如下: +1、原子性 + + 保证任务中的所有操作都执行完毕;否则,事务会在出现错误时终止,并回滚之前所有操作到原始状态。 +2、一致性 + + 事务必须使数据库从一个一致性状态变换到另一个一致性状态。 + 3、隔离性 + + 保证不同的事务相互独立、透明地执行。 +  隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。 + + 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 +4、持久性 + + 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 +## 三、事务分类 + 1、显式事务 + + 用 begin transaction 明确指定事务的开始,由 commit transaction 提交事务、rollback transaction 回滚事务到事务结束。 + 2、隐式事务 + + 通过设置 set implicit_transactions on 语句,将隐式事务模式设置为打开。当以隐式事务模式操作时,不必使用 begin transaction 开启事务,当一个事务结束后,这个模式会自动启用下一个事务。只需使用 commit transaction 提交事务或 rollback transaction 回滚事务即可。 + 3、自动提交事务 + + SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。 +## 事务流程 + 事务执行流程:开始事务(begin transaction)-->if(成功) 提交(commit transaction) else:回滚(rollback transaction) + +## 事务练习(BankTest): + +1.--假设刘备取款6000,(添加check约束,设置账户余额必须>=0),要求:使用事务实现,修改余额和添加取款记录两步操作使用事务 +```sql +begin transaction +declare @mon money = 6000 +declare @no varchar(20) +declare @err int = 0 --一开始所有语句都没有错误 +select @no = cardno from BankCard where AccountId=(select AccountId from AccountInfo where RealName='刘备') +update BankCard set CardMoney=CardMoney-@mon where AccountId=(select AccountId from AccountInfo where RealName='刘备') +set @err += @@ERROR +insert CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) values(@no,0,@mon,getdate()) + + +if @err>0 + begin + print '事务提交失败' + rollback transaction + end +else + begin + print '事务提交成功' + commit transaction + end +``` +2.--刘备向张飞转账1000元,(添加check约束,设置账户余额必须>=0) +```sql +begin transaction + declare @myerr int = 0 + declare @CardNo1 varchar(200),@CardNo2 varchar(200),@money money = 1000 + select @CardNo1= CardNo from BankCard where AccountId = (select AccountId from AccountInfo where RealName='刘备') + select @CardNo2= CardNo from BankCard where AccountId = (select AccountId from AccountInfo where RealName='张飞') + update BankCard set CardMoney = CardMoney-@money where AccountId = (select AccountId from AccountInfo where RealName='刘备') + set @myerr = @myerr + @@ERROR + update BankCard set CardMoney = CardMoney+@money where AccountId = (select AccountId from AccountInfo where RealName='张飞') + set @myerr = @myerr + @@ERROR + --银行卡交易记录 + insert CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) values(@CardNo1,0,1000,GETDATE()) + insert CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) values(@CardNo2,1000,0,GETDATE()) + --转账记录 + insert CardTransfer(CardNoOut,CardNoIn,TransferMoney,TransferTime) values(@CardNo1,@CardNo2,@money,GETDATE()) + +if @myerr = 0 + begin + commit transaction + print '转账成功' + end +else + begin + rollback transaction + print '转账失败' + end +``` \ No newline at end of file -- Gitee