zoukankan      html  css  js  c++  java
  • 5事务处理

    1.事物的概念

    数据库中的事物是一种机制,每一个事物是一个独立的工作单元,它包含了一组数据库操作命令,且这组命令要么都执行,要么都不执行,是一个不可分割的工作逻辑单元

    •事务的四大特性是?
    (1).原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。

    (2)一致性(Consistency):当事务完成时,数据必须处于一致状态。

    (3)隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。

    (4)永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。

    •事务的分类

    (1)显示事务:用BEGIN TRANSACTION明确指定事务的开始,这是最常用的事务类型

    (2)隐性事务:通过设置SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开,下一个语句自动启动一个新事务。当该事务完成时,再下一个 T-SQL 语句又将启动一个新事务

    (3)自动提交事务:这是 SQL Server 的默认模式,它将每条单独的 T-SQL 语句视为一个事务,如果成功执行,则自动提交;如果错误,则自动回滚。

    2.事物的使用

    •创建事物

    用T-SQL语句创建事物

    ①开始事物:begin transaction

    ②提交事务:commit transaction

    ③回滚事物:rollback transaction

    •创建事物的原则

    ①事务要尽可能的简短

    ②在事务中访问的数据量要尽量最少

    ③浏览数据是尽量不要打开事务

    ④在事务处理期间不要请求用户输入

    •使用事物的注意事项

    ①在每个操作之后,都要检查@@error或rowcount的值;

    ②当一个事务结束之后,紧跟在事务之后的T-SQL代码可以继续执行,但是出错后不能再回滚事务了;

    ③已经提交完毕的事务会将数据正式写入数据库;

    ④在一个事务执行时,如果发生如断电等意外事件,则在下次重新启动系统时,该事务会自动回滚;

    ⑤在事务里发生错误是的事务无法执行下去,事务也会自动回滚;

    ⑥无法回滚的语句不能在事务中使用。

    •事物的隔离级别
    在SQL Server 中事务的隔离级别由低到高分为5个级别:
    (1).Read uncommitted:不隔离数据
    (2).Read committed:不允许读取没有提交的数据
    (3).Repeatable Read:在事务中锁定所读取的数据不让别人修改和删除。
    (4).Snashot:快照隔离,可以为读取数据的事务提供所需数据的一个已提交的版本。
    (5).Serializable:将事务所要用到的数据表全部锁定,不与许其它事务添加、修改和删除数据。

    3.事务的工作原理
    (1).在事务开始时,SQLServer会将要修改的数据锁定,同时创建一个临时的事务日志,在该临时的事务日志里存放更改的数据和更改的存储过程。
    (2).在事务未提交之前,事务中所有的数据操作是临时的,一旦发生数据操作失败,就使用临时日志里的数据去回滚事务操作,并解除锁定。在事务 被成功提交后,数据库就将临时的事务日志的内容存储到数据库中,此时事务操作完成。

    4.示例:

    ---------------------------------------没使用事物的sql语句-------------------------------------------
    --判断数据库是否存在
    if DB_ID ('Bank')is not null
     drop database Bank 
     --创建数据库
     create database Bank
     go 
     use Bank
     go
     --判断表是否存在
     if OBJECT_ID('accountInfo','table')is not null
     drop table accountInfo
     --创建表
     create table accountInfo
     (
        accountName varchar(10),
        currentMoney money
     );
     go
     --添加约束:根据银行规定,账户余额不能小于1元
     alert table accountInfo
        add constraint CK_accountInfo_currentMoney check(currentMoney>=1)
    go
    --插入测试数据
    insert into accountInfo values('莱钢集团',2000000)
    insert into accountInfo values('保利集团',2000000)
    
    --模拟转账:保利建设通过转账,直接支付给莱钢集团购买钢材的预付款200万
    use Bank
    go
    --转账过程
    --1.保利建设账户减少200万
    update accountInfo set currentMoney=currentMoney-2000000 where accountName='保利建设'
    --2.莱钢集团账户增加200万
    update accountInfo set currentMoney=currentMoney+2000000 where accountName='莱钢集团'
    go
    --通过执行转账sql语句可发现莱钢集团的账户变为了400万,而保利建设的账户并没有减少。
    --这是两家公司的余额总和为600万,多出了200万,这样是不符合逻辑的。
    
    -----------------------------------使用了事物的sql语句----------------------------------------------
    use Bank
    go
     print'转账前的账户金额' 
     select * from accountInfo
     declare @money money --声明一个变量,用于存储转账的金额
     set @money=2000000  --设置转账金额为200万
     
     declare @errorSum int --声明一个变量用于存储累加错误
     set @errorSum=0 --初始化,表示没有错误
     --执行update语句,开始事务
     begin transaction
     --1.保利建设账户减少200万
     update accountInfo set currentMoney=currentMoney-@money where accountName='保利建设'
     set @errorSum=@errorSum+@@ERROR--累加错误
     
     --2.莱钢集团账户增加200万
     update accountInfo set currentMoney=currentMoney+@money where accountName='莱钢集团'
     set @errorSum=@errorSum+@@ERROR
     
     if (@errorSum<>0)
      begin 
        print '转账失败,回滚事务。'
        rollback transaction
      end
      else 
      begin 
        commit transaction --提交事务
      end
     go
     print '转账后的金额'
     select * from accountInfo
     

    在存储过程中使用事务

    --在存储过程中使用事务
    use Bank
    go
    if exists(select 1 from sysobjects where name='proc_transfer')
        drop procedure proc_transfer
    go
    --创建转账的存储过程
    create procedure proc_transfer
        --包含三个输入参数
        @intoAccountName varchar(20),--转入账户
        @outAccountName varchar(20),--转出账户
        @money money --转账金额
    as
       --判断账户名是否存在
       if not exists(slect 1 from accountInfo where accountName=@intoaccountName)
    begin 
        print'转入账户不存在。'
        return
    end
    if not exists(select 1 from accountInfo where accountName=@outaccountName)
    begin 
        print'转出账户不存在。'
        return
    end
        declare @errorSum int 
        set @errorSum=0
    begin transaction
        update accountInfo set currentMoney=currentMoney-@money where accountName=@outaccountName
        set @errorSum=@errorSum+@@ERROR
        update accountInfo set currentMoney=currentMoney+@money where accountName=@intoaccountName
        set @errorSum=@errorSum+@@ERROR
        
        if(@errorSum<>0)
    begin 
        print'转账失败,回滚事务。'
        rollback transaction
    end
        else
    begin
        print'转账成功!'
        commit transaction
    end
    go
     
  • 相关阅读:
    angular反向代理配置
    实现对Asp.NetMvc及Asp.NetCore的权限控制
    C# 语言特性发展史
    在angular 6中使用 less
    使用WeihanLi.Redis操作Redis
    [svc]jq神器使用
    [sh]shell脚本栗子
    [k8s]nginx-ingress配置4/7层测试
    [svc]nginx-module-vts第三方模块安装配置
    [k8s]helm原理&私有库搭建&monocularui和kubeapp探究
  • 原文地址:https://www.cnblogs.com/chef5-3/p/3133584.html
Copyright © 2011-2022 走看看