码迷,mamicode.com
首页 > 其他好文 > 详细

事务处理

时间:2015-01-13 15:47:59      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

事务(Transaction)

  是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割工作单位。通过事务,SQLServer能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。
  事务通常是以BEGINTRANSACTION开始,以COMMIT或ROLLBACK结束。
  COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。
  ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有以完成的操作全部撤消,滚回到事务开始的状态。
事务的特性(ACID特性)   

     A:原子性(Atomicity)       

         事务是一个完整的操作,事务的各步操作是不可分的(原子的),要么都执行,要么都不执行   

     B:一致性(Consistency)       

         事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。   

     C:隔离性(Isolation)         

        一个事务的执行不能被其他事务干扰。     

      D:持续性/永久性(Durability)     

        一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

 -------示例------------------------------------------------------------

创建示例表

CREATE TABLE acc(
    ID  NUMBER(19),
    NAME VARCHAR2(20)    NOT NULL,   --不能为空
    bal   NUMBER(19,3)    NOT NULL,
    CONSTRAINT pd_id PRIMARY KEY(ID),  --主健约束
    CONSTRAINT ck_bal   CHECK(bal>=0)  --检查约束
);
SELECT * FROM acc;
INSERT INTO acc VALUES(1001,张三,3000);
INSERT INTO acc VALUES(1002,张三,1);

示例一:模拟银行转账业务

A:原子性(Atomicity)       

         事务是一个完整的操作,事务的各步操作是不可分的(原子的),要么都执行,要么都不执行   

BEGIN
  UPDATE acc SET bal=bal-4000 WHERE ID=1001;            --转出4000,但余额只有3000;
    UPDATE acc SET bal=bal-4000 WHERE ID=1001;          --转入4000
    COMMIT;                                              --提交事务
    EXCEPTION                                           --1001账户转出时会有异常,
      WHEN OTHERS THEN                                  --捕获导常
        dbms_output.put_line(账户异常,转账失败!);      --提示信息
        ROLLBACK;                                       --将数据回滚到转账前
END;
--查询发现数据已经回到转账前
SELECT * FROM acc;

 B:一致性(Consistency)       

         事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。   

DECLARE
  v_a                  acc.bal%TYPE;            --余额类型
  v_b                  acc.bal%TYPE; 
  v_sal                acc.bal%TYPE;            --计算总金额
BEGIN
  SELECT bal INTO v_a FROM acc WHERE ID=1001;   --将账户A的余额查出
  SELECT bal INTO v_b FROM acc WHERE ID=1002;   --将账户B的余额查出
  dbms_output.put_line(转账前A的余额: ||v_a);
  dbms_output.put_line(转账前B的余额: ||v_b);
  dbms_output.put_line(转账前A和B的总余额: ||(v_a+v_b));
  
  --开始转账
  UPDATE acc SET bal=bal-2000 WHERE ID=1001;
  UPDATE acc SET bal=bal+2000 WHERE ID=1002;
  COMMIT;                                                      --提交
   SELECT bal INTO v_a FROM acc WHERE ID=1001;        --将账户A的余额查出
  SELECT bal INTO v_b FROM acc WHERE ID=1002;         --将账户B的余额查出
  dbms_output.put_line(转账后A的余额: ||v_a);
  dbms_output.put_line(转账后B的余额: ||v_b);
  dbms_output.put_line(转账后A和B的总余额: ||(v_a+v_b));
  
  EXCEPTION 
    WHEN OTHERS THEN
    dbms_output.put_line(账户异常,转账失败);
     --回退到转账前
    ROLLBACK;         
                                      
            --                         失败时账户余额  
  SELECT bal INTO v_a FROM acc WHERE ID=1001;        --将账户A的余额查出
  SELECT bal INTO v_b FROM acc WHERE ID=1002;         --将账户B的余额查出
  dbms_output.put_line(失败时A的余额: ||v_a);
  dbms_output.put_line(失败时B的余额: ||v_b);
  dbms_output.put_line(失败时A和B的总余额: ||(v_a+v_b));
END;

 

事务处理

标签:

原文地址:http://www.cnblogs.com/hjiongjiong/p/4221390.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!