Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 读已提交或可序列化_Sql_Oracle - Fatal编程技术网

Sql 读已提交或可序列化

Sql 读已提交或可序列化,sql,oracle,Sql,Oracle,这是一个实践,我不知道哪一个更好,谢谢你的建议 CREATE OR REPLACE PROCEDURE INSERT_ORDER( oid IN NUMBER, ccode IN VARCHAR, eid IN NUMBER) AS total CUSTOMER.TOTAL_ORDERS%TYPE; BEGIN INSERT INTO ORDERS VALUES(oid, ccode, eid, sysdate, sysdate + 5, s

这是一个实践,我不知道哪一个更好,谢谢你的建议

CREATE OR REPLACE PROCEDURE INSERT_ORDER(
    oid    IN NUMBER,
    ccode  IN VARCHAR,
    eid    IN NUMBER)
AS
    total CUSTOMER.TOTAL_ORDERS%TYPE;
BEGIN
    INSERT INTO ORDERS VALUES(oid, ccode, eid, sysdate, sysdate + 5, sysdate + 1,
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

    SELECT TOTAL_ORDERS
    INTO total
    FROM CUSTOMER
    WHERE CUSTOMER.CUSTOMER_CODE = ccode;

    total := total + 1;

    UPDATE CUSTOMER
    SET TOTAL_ORDERS = total
    WHERE CUSTOMER.CUSTOMER_CODE = ccode;

    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE( SQLERRM );
        ROLLBACK;
END;
决定应处理程序插入顺序的隔离级别,并证明您的决定是正确的。 您有以下两个选项:读取已提交或可序列化

如果您决定可以在读提交级别处理该过程,则 您的决定的理由提供了一个证据,证明 处于读取提交级别的过程不会损坏示例数据库

如果您决定该过程可以在可序列化级别上处理,则作为 对齐在读取提交时提供过程的并发处理
破坏数据库的级别。

1.读取提交的隔离级别:它是默认级别。每个查询(在事务中)只能看到在该查询开始之前提交的数据。因此,如果在同一事务中运行同一查询两次,您可能会看到不同的结果和幻影,因为其他会话可能会更改数据

2.SERIALIZABLE隔离级别:每个查询(在事务内)只能看到在该事务开始之前提交的数据,以及在事务本身中所做的更改

让我们拆分事务中的操作:

INSERT INTO ORDERS VALUES(oid, ccode, eid, sysdate, sysdate + 5, sysdate + 1,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
第一种方法是在orders表中插入数据,这取决于过程提供的输入值。您没有提供有关约束或主键的此表的任何说明。如果Oid是OrderId,我想它不能被复制,因此不能用不同的值调用它

有趣的是:

SELECT TOTAL_ORDERS
INTO total
FROM CUSTOMER
WHERE CUSTOMER.CUSTOMER_CODE = ccode;
在READ COMMITTED中,该部分受制于phantom,因为如果有人在几乎相同的时间为同一客户下了另一个订单,它可以检索到您期望的不同值。为了避免这种情况,无论其他会话中发生了什么,您都可以及时获得客户的总订单,请使用SERIALIZABLE

最后你终于做到了

UPDATE CUSTOMER
SET TOTAL_ORDERS = total
WHERE CUSTOMER.CUSTOMER_CODE = ccode;
这里适用同样的规则。由于之前使用select的值计算了total,所以在READ COMMITED中,您将遇到与之前相同的问题

对于我来说,这里最重要的部分是,在根据SELECT INTO完成更新时,数据的一致性有多重要

  • 如果您的答案是肯定的,我希望总数能够及时反映当时的值,无论其他会话中发生了什么,请使用SERIALIZABLE
  • 如果您的答案是肯定的,我希望这个数字能够反映当时多用户环境中总数的实际值,请使用READ COMMITTED

关于

1。读取提交的隔离级别:它是默认级别。每个查询(在事务中)只能看到在该查询开始之前提交的数据。因此,如果在同一事务中运行同一查询两次,您可能会看到不同的结果和幻影,因为其他会话可能会更改数据

2.SERIALIZABLE隔离级别:每个查询(在事务内)只能看到在该事务开始之前提交的数据,以及在事务本身中所做的更改

让我们拆分事务中的操作:

INSERT INTO ORDERS VALUES(oid, ccode, eid, sysdate, sysdate + 5, sysdate + 1,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
第一种方法是在orders表中插入数据,这取决于过程提供的输入值。您没有提供有关约束或主键的此表的任何说明。如果Oid是OrderId,我想它不能被复制,因此不能用不同的值调用它

有趣的是:

SELECT TOTAL_ORDERS
INTO total
FROM CUSTOMER
WHERE CUSTOMER.CUSTOMER_CODE = ccode;
在READ COMMITTED中,该部分受制于phantom,因为如果有人在几乎相同的时间为同一客户下了另一个订单,它可以检索到您期望的不同值。为了避免这种情况,无论其他会话中发生了什么,您都可以及时获得客户的总订单,请使用SERIALIZABLE

最后你终于做到了

UPDATE CUSTOMER
SET TOTAL_ORDERS = total
WHERE CUSTOMER.CUSTOMER_CODE = ccode;
这里适用同样的规则。由于之前使用select的值计算了total,所以在READ COMMITED中,您将遇到与之前相同的问题

对于我来说,这里最重要的部分是,在根据SELECT INTO完成更新时,数据的一致性有多重要

  • 如果您的答案是肯定的,我希望总数能够及时反映当时的值,无论其他会话中发生了什么,请使用SERIALIZABLE
  • 如果您的答案是肯定的,我希望这个数字能够反映当时多用户环境中总数的实际值,请使用READ COMMITTED

你说的腐败是什么意思?事务不会损坏任何东西,无论是可序列化的还是已提交的读取,这只是它们处理隔离级别的方式。假设过程INSERT_ORDER可以由许多不同的用户同时处理。请阅读以下内容:我为您提供了答案,请随意评论您的疑问it@RobertoHernandez我需要一些时间来完全理解它,非常感谢你。为什么要改变?你说的腐败是什么意思?事务不会损坏任何东西,无论是可序列化的还是已提交的读取,这只是它们处理隔离级别的方式。假设过程INSERT_ORDER可以由许多不同的用户同时处理。请阅读以下内容:我为您提供了答案,请随意评论您的疑问it@RobertoHernandez我需要一些时间来完全理解它,非常感谢你。为什么改变是为了感谢你和“如果你的答案是……”小姐是或否?嗨@ USER 138629,如果你认为答案是有效的,请投票或接受它。真的很感激,如果答案是否定的呢?两个前提的答案怎么可能都是否定的呢。或者您希望更新反映所有订单的状态,或者您只反映当前交易中的状态,谢谢“如果您的答案是……”小姐是或否?HI @ USER 138629,如果您认为答案是有效的,请投票或接受它。真的很感激,如果答案是否定的呢