事务基础

事务:代表一个业务边界(业务逻辑的多条语句组成)
比如:博客管理系统(用户实体,板块实体,主贴实体,回帖实体)回帖业务
  
  1、用户向回帖表中插入一条记录

  INSERT INTO REPLY VALUES ....

  2、回帖用户积分+3

  UPDATE USER SET SCORE = SCORE + 3 WHERE USERNAME = '回帖用户';

  3、发帖用户积分+5

  UPDATE USER SET SCORE = SCORE + 5 WHERE USERNAME = '发帖用户';

  上述三个步骤(语句)是一个业务整体

事务的特性 ACID

  • 原子性(Atomicity):事务是一个整体的工作单元,事务对数据库所做的操作要么全部执行,要么全部取消。如果某条语句执行失败,则所有语句全部回滚。
  • 一致性(Consistency):事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。如果事务成功,则所有数据将变为一个新的状态;如果事务失败,则所有数据将处于开始之前的状态。
  • 隔离性(Isolation):事务与事务之间是相互隔离的

     由事务所作的修改必须与其他事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

  • 持久性(Durability):事务提交后,对数据库数据的影响是持久性(永久的)

事务的操作

  •   事务提交 COMMIT;
  •   事务回滚 ROLLBACK
  •   事务保存点 SAVEPOINT
  •   执行一条数据定义语句,比如,CREATE、DROP或ALTER等语句。如果该语句执行成功,那么Oracle系统会自动执行COMMIT命令;否则,则Oracle系统会自动执行ROLLBACK命令。
  •   执行一个数据控制命令,比如,GRANT、REVOKE等控制命令,这种操作执行完毕,Oracle系统会自动执行COMMIT命令。
  •   正常地断开数据库的连接、正常地退出SQL*Plus环境,则Oracle系统会自动执行COMMIT命令;否则,则Oracle系统会自动执行ROLLBACK命令。

案例:

-- 创建一个账号表
CREATE TABLE ACCOUNT(
    ACC_ID INT PRIMARY KEY,
    ACC_NAME VARCHAR2(20),
    ACC_BALANCE NUMBER(10,2) CONSTRAINT CK_ACCOUNT_BALANCE CHECK(ACC_BALANCE >= 0) --账户余额不能小于0
);

-- 插入两条测试数据
INSERT INTO ACCOUNT VALUES (10,'PEPPA',1000);
INSERT INTO ACCOUNT VALUES (20,'SUZY',1000);
-- 提交事务
COMMIT;
SELECT * FROM ACCOUNT;

-- 转账操作
DECLARE
    BALANCEEXCEPTION EXCEPTION;
    PRAGMA EXCEPTION_INIT(BALANCEEXCEPTION,-02290);
v_money number(10,2) := 500;
BEGIN
    UPDATE ACCOUNT SET ACC_BALANCE = ACC_BALANCE + v_money WHERE ACC_NAME='SUZY';
    UPDATE ACCOUNT SET ACC_BALANCE = ACC_BALANCE - v_money WHERE ACC_NAME='PEPPA';
    -- 如果没有异常,转账成功,提交事务
    COMMIT;
EXCEPTION  -- 自定义异常发生,转账失败,回滚事务
    WHEN BALANCEEXCEPTION THEN
         DBMS_OUTPUT.put_line('转账失败');
         ROLLBACK;
END;

-- 事务保存点
DECLARE
    BALANCEEXCEPTION EXCEPTION;
    PRAGMA EXCEPTION_INIT(BALANCEEXCEPTION,-02290);
v_money number(10,2) := 5000;
BEGIN
    INSERT INTO ACCOUNT VALUES (30,'EMILY',1000);
    INSERT INTO ACCOUNT VALUES (40,'PEDRO',1000);
    -- 定义一个事务保存点(保存点可以定义多个)
    SAVEPOINT INSERT_POINT;
    -- 再次转账
    UPDATE ACCOUNT SET ACC_BALANCE = ACC_BALANCE + v_money WHERE ACC_NAME='SUZY';
    UPDATE ACCOUNT SET ACC_BALANCE = ACC_BALANCE - v_money WHERE ACC_NAME='PEPPA';
    -- 如果没有异常,转账成功,提交事务
    COMMIT;
EXCEPTION
    WHEN BALANCEEXCEPTION THEN
         DBMS_OUTPUT.put_line('转账失败');
         -- 回滚事务到指定保存点
         ROLLBACK TO INSERT_POINT;
         -- 提交其它业务操作(保存点之前的业务)
         COMMIT;
END;

事务高级知识在Spring章节

posted @ 2021-04-20 16:24  Tiger-Adan  阅读(672)  评论(0编辑  收藏  举报