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,如果您认为答案是有效的,请投票或接受它。真的很感激,如果答案是否定的呢