【问题标题】:Prevent concurrency bugs on transactions on Oracle防止 Oracle 上事务的并发错误
【发布时间】:2021-04-07 06:15:59
【问题描述】:

我有一个为客户创建贷款的程序。客户最多只能获得 10000 个。 我首先阅读客户要求的旧贷款金额,如果客户要求的金额超过 10000,我提出错误,否则我插入新贷款。

create or replace NONEDITIONABLE PROCEDURE CREATE_LOAN
( 
    p_client_id INT,
    p_requested_loan_amount DECIMAL
)
IS
    v_available_amount DECIMAL DEFAULT 0;
BEGIN
    --Get available amount for the client( Clients cant require more thant 10000)
    SELECT 10000 - COALESCE(SUM(l.amount), 0) INTO v_available_amount
    FROM loans l
    WHERE l.client_id = p_client_id
    AND (l.state_id = 1 OR l.state_id = 2);
    
    --If the cliente requested more than 10000 in older loans raise error
    IF  p_requested_loan_amount > v_available_amount
    THEN
        raise_application_error( -20001, 'Not enough available amount.' );
    END IF; 
    
    --Else insert new loan
    INSERT INTO loans (amount, state_id, client_id)
    VALUES(p_requested_loan_amount, 1, p_client_id);
END;

如何防止两个并发交易同时读取旧贷款并且都相信他们在插入之前有可用金额。如果我使用的是 Sql Server,我可以提高隔离级别,这样可以防止出现问题,但它在 Oracle 上的工作方式不同。

【问题讨论】:

    标签: oracle transactions isolation-level


    【解决方案1】:

    在您的 SELECT 语句中,使用 FOR UPDATE 子句。这将获得一个行锁并阻止另一个事务也锁定该行。

    https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4530093713805

    【讨论】:

    • 为什么 Serializable 隔离级别不能在 oracle 上阻止这种情况?
    • 在 oracle 中您似乎看不到 phatom 读取寄存器。
    猜你喜欢
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2017-11-09
    • 2016-04-01
    • 2015-07-31
    • 2020-12-11
    相关资源
    最近更新 更多