数据仓库服务 GAUSSDB(DWS)-事务管理:事务场景示例

时间:2024-01-26 16:15:18

事务场景示例

某顾客在商店使用电子支付购买100元的物品,当中至少包括两个操作:1. 该顾客的账户减少100元。2. 商店账户(商户)增加100元。支持事务的数据库管理系统就是要确保以上两个操作(整个“事务”)都能完成,或一起取消。

  1. 创建样例数据:
    创建一个简单的用户金额表并向表中插入数据(假设商户和顾客的账户上各有500元)。
    1
    2
    3
    4
    5
    CREATE TABLE customer_info (
    	NAME VARCHAR(32) PRIMARY KEY,
    	MONEY INTEGER
    );
    INSERT INTO customer_info (name, money) VALUES ('buyer', 500), ('shop', 500);
    
    查看表数据显示商户和顾客各有500元。
    1
    2
    3
    4
    5
    6
    SELECT * FROM customer_info;
     name  | money
    -------+-------
     buyer |   500
     shop  |   500
    (2 rows)
    
  2. 普通操作(正常模式)。

    模拟正常购买过程,顾客先扣款100元,商户再增加款额100元。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE customer_info SET money = money-100 WHERE name IN (SELECT name FROM customer_info WHERE name = 'buyer');
    UPDATE customer_info SET money = money+100 WHERE name IN (SELECT name FROM customer_info WHERE name = 'shop');
    
    SELECT * FROM customer_info;
     name  | money
    -------+-------
     buyer |   400
     shop  |   600
    (2 rows)
    
  3. 恢复初始值。
    1
    2
    3
    4
    5
    6
    7
    UPDATE customer_info SET money=500;
    select * from customer_info;
     name  | money
    -------+-------
     shop  |   500
     buyer |   500
    (2 rows)
    
  4. 普通操作(异常模式)。

    模拟购买过程出现状况,顾客发生扣款100元,商户没有增加款额。

    1. 顾客先扣款100元。
      1
      UPDATE customer_info SET money = money-100 WHERE name IN (SELECT name FROM customer_info WHERE name = 'buyer');
      
    2. 商户发现支付有问题,终止了后续交易。商户增加款操作直接报错,终止执行下面的语句。(仅商户觉得支付有问题)
      1
      UPDATE customer_info SET money = money+100 WHERE name IN (SELECT name FROM customer_info WHERE name = 'shop');
      
    3. 查询结果发现:消费者已经扣款,但商户没增加款额,这里顾客的金额了100元。
      1
      2
      3
      4
      5
      6
      SELECT * FROM customer_info;
       name  | money
      -------+-------
       buyer |   400
       shop  |   500
      (2 rows)
      

因此,如果没有事务,一旦SQL语句中间出现异常,整个账户系统的收支就不平衡了。

使用数据库事务,模拟出现异常操作时,进行事务回滚。
  1. 恢复初始值:
    1
    UPDATE customer_info SET money=500;
    
  2. 开启事务后,顾客先扣款100元。
    1
    2
    BEGIN TRANSACTION;
    UPDATE customer_info SET money = money-100 WHERE name IN (SELECT name FROM customer_info WHERE name = 'buyer');
    
  3. 商户增加款额操作直接报错,终止执行下面的语句。
    1
    UPDATE customer_info SET money = money+100 WHERE name IN (SELECT name FROM customer_info WHERE name = 'shop');
    
  4. 回滚事务,在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销。
    1
    2
    3
    4
    ERROR:  syntax error at or near "shop"
    LINE 1: ...e IN (SELECT name FROM customer_info WHERE name = ''shop'');
    END TRANSACTION;
    ROLLBACK
    
  5. 查询显示顾客和商户的账户金额仍旧完整一致。即数据库在事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,数据库的完整性没有被破坏。
    1
    2
    3
    4
    5
    6
    SELECT * FROM customer_info;
     name  | money
    -------+-------
     buyer |   500
     shop  |   500
    (2 rows)
    
support.huaweicloud.com/sqlreference-820-dws/dws_06_0117.html