Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.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
Oracle 如何确保所有事务都已提交或回滚?_Oracle_Plsql - Fatal编程技术网

Oracle 如何确保所有事务都已提交或回滚?

Oracle 如何确保所有事务都已提交或回滚?,oracle,plsql,Oracle,Plsql,我有一个PL/SQL过程,例如: procedure MyProcedure() is begin insert into table1 (field1, Field2) values ('value1','value2'); -- do some staff insert into table2 (field1, Field2) values ('value1','value2'); -- do some staff delete from

我有一个PL/SQL过程,例如:

procedure MyProcedure() is 
begin 
    insert into table1 (field1, Field2) values ('value1','value2');

    -- do some staff

    insert into table2 (field1, Field2) values ('value1','value2');

    -- do some staff

    delete from table3 where id = xx;

    -- do some staff
end;
一些程序说明可能会失败,我希望所有说明之间保持一定的一致性。这意味着,如果一条指令失败,我希望所有其他指令都回滚。所以要么一切都被执行,要么什么都不执行

有人知道怎么做吗

先谢谢你


干杯,

在结束时做出一个
提交
回滚-就是这样。当然,只有在中间没有执行隐式提交的命令时,才能获得预期的行为,例如,
TRUNCATE TABLE…

最后执行
提交
回滚-就是这样。当然,只有在中间没有执行隐式提交的命令时,才能获得预期的行为,例如,
TRUNCATE TABLE…

如果发生任何错误,可以引发异常并回滚,如果没有发生错误,则可以添加提交。 注意,如果将来添加任何DDL语句(create、alter),这些语句将被提交

BEGIN

insert into table1 (field1, Field2) values ('value1','value2');

-- do some staff

insert into table2 (field1, Field2) values ('value1','value2');

-- do some staff

delete from table3 where id = xx;
commit;
  -- if any error occured
   WHEN OTHERS THEN  
 rollback;
END; 
/

如果发生任何错误,可以引发异常并回滚,如果未发生错误,则可以添加提交。 注意,如果将来添加任何DDL语句(create、alter),这些语句将被提交

BEGIN

insert into table1 (field1, Field2) values ('value1','value2');

-- do some staff

insert into table2 (field1, Field2) values ('value1','value2');

-- do some staff

delete from table3 where id = xx;
commit;
  -- if any error occured
   WHEN OTHERS THEN  
 rollback;
END; 
/

事务控制最好发生在被调用的地方,而不是在过程内部,除非它是自治事务

procedure MyProcedure( ret_status out int ) is
..
..
调用(可以是另一个过程/块或Web应用程序)


此外,最好在异常部分调用日志过程或带有相关错误消息的
dbms\u输出。

事务控制最好发生在被调用的地方,而不是在过程内部,除非它是自治事务

procedure MyProcedure( ret_status out int ) is
..
..
调用(可以是另一个过程/块或Web应用程序)


此外,最好在异常部分调用日志过程或带有相关错误消息的
dbms\u输出。

您要求的或多或少是默认行为:

create table test1 (id integer not null);
create table test2 (id integer not null);
create table test3 (id integer not null);

create or replace procedure myProcedure
    ( p1 test1.id%type
    , p2 test2.id%type
    , p3 test3.id%type )
as
begin
    insert into test1 (id) values (p1);
    insert into test2 (id) values (p2);
    insert into test3 (id) values (p3);
end myProcedure;
/

call myProcedure(1, 2, 3);
-- completes successfully

call myProcedure(1, 2, null);
-- fails with:
-- ERROR at line 1:
-- ORA-01400: cannot insert NULL into ("WILLIAM"."TEST3"."ID")
-- ORA-06512: at "WILLIAM.MYPROCEDURE", line 9

select 'test1' as table_name, test1.id from test1 union all
select 'test2', test2.id from test2 union all
select 'test3', test3.id from test3
order by 1;

TABLE         ID
----- ----------
test1          1
test2          2
test3          3

3 rows selected.
因此,我有成功调用中的三行,失败调用中没有任何行,所有这些都没有显式提交或回滚

如果您真的希望提交,可以在过程的末尾添加一个
commit
(这并不总是一个好主意,但要求各不相同)

但是,只有当异常一直传播到调用方时,才会发生默认的“回滚到隐式保存点”行为,例如,如果我尝试使用以下方法处理它:

begin
    delete test1;
    delete test2;
    delete test3;

    myProcedure(1, 2, null);
exception
    when others then
        dbms_output.put_line(sqlerrm);
        dbms_output.put_line(dbms_utility.format_error_backtrace);
end;

ORA-01400: cannot insert NULL into ("WILLIAM"."TEST3"."ID")
ORA-06512: at "WILLIAM.MYPROCEDURE", line 9
ORA-06512: at line 6

PL/SQL procedure successfully completed.
现在,由于块成功完成,我有部分失败的运行的值:

select 'test1' as table_name, test1.id from test1 union all
select 'test2', test2.id from test2 union all
select 'test3', test3.id from test3
order by 1;

TABLE         ID
----- ----------
test1          1
test2          2

2 rows selected.
无论如何,要明确地处理所有这些问题,您可能需要以下内容:

create or replace procedure myProcedure
    ( p1 test1.id%type
    , p2 test2.id%type
    , p3 test3.id%type )
as
begin
    savepoint start_of_processing;

    insert into test1 (id) values (p1);
    insert into test2 (id) values (p2);
    insert into test3 (id) values (p3);

    commit;
exception
    when others then
        rollback to start_of_processing;
        -- Log using whatever logging package you have:
        logger.message('Something appears to have gone disastrously amiss');
        raise;
end myProcedure;

不过,请记住这一点。据我所知,这在所有编程语言中都是正确的。

您要求的或多或少是默认行为:

create table test1 (id integer not null);
create table test2 (id integer not null);
create table test3 (id integer not null);

create or replace procedure myProcedure
    ( p1 test1.id%type
    , p2 test2.id%type
    , p3 test3.id%type )
as
begin
    insert into test1 (id) values (p1);
    insert into test2 (id) values (p2);
    insert into test3 (id) values (p3);
end myProcedure;
/

call myProcedure(1, 2, 3);
-- completes successfully

call myProcedure(1, 2, null);
-- fails with:
-- ERROR at line 1:
-- ORA-01400: cannot insert NULL into ("WILLIAM"."TEST3"."ID")
-- ORA-06512: at "WILLIAM.MYPROCEDURE", line 9

select 'test1' as table_name, test1.id from test1 union all
select 'test2', test2.id from test2 union all
select 'test3', test3.id from test3
order by 1;

TABLE         ID
----- ----------
test1          1
test2          2
test3          3

3 rows selected.
因此,我有成功调用中的三行,失败调用中没有任何行,所有这些都没有显式提交或回滚

如果您真的希望提交,可以在过程的末尾添加一个
commit
(这并不总是一个好主意,但要求各不相同)

但是,只有当异常一直传播到调用方时,才会发生默认的“回滚到隐式保存点”行为,例如,如果我尝试使用以下方法处理它:

begin
    delete test1;
    delete test2;
    delete test3;

    myProcedure(1, 2, null);
exception
    when others then
        dbms_output.put_line(sqlerrm);
        dbms_output.put_line(dbms_utility.format_error_backtrace);
end;

ORA-01400: cannot insert NULL into ("WILLIAM"."TEST3"."ID")
ORA-06512: at "WILLIAM.MYPROCEDURE", line 9
ORA-06512: at line 6

PL/SQL procedure successfully completed.
现在,由于块成功完成,我有部分失败的运行的值:

select 'test1' as table_name, test1.id from test1 union all
select 'test2', test2.id from test2 union all
select 'test3', test3.id from test3
order by 1;

TABLE         ID
----- ----------
test1          1
test2          2

2 rows selected.
无论如何,要明确地处理所有这些问题,您可能需要以下内容:

create or replace procedure myProcedure
    ( p1 test1.id%type
    , p2 test2.id%type
    , p3 test3.id%type )
as
begin
    savepoint start_of_processing;

    insert into test1 (id) values (p1);
    insert into test2 (id) values (p2);
    insert into test3 (id) values (p3);

    commit;
exception
    when others then
        rollback to start_of_processing;
        -- Log using whatever logging package you have:
        logger.message('Something appears to have gone disastrously amiss');
        raise;
end myProcedure;

不过,请记住这一点。据我所知,这在所有编程语言中都是正确的。

您可以添加一个异常,如果发生任何错误,则引发一个异常,您可以在其内部添加回滚。您可以添加一个异常,如果发生任何错误,则引发一个异常,您可以在其内部添加回滚