oracle中是否有内置的自动提交功能?
就像我想要更新一百万行,并且我想将自动提交设置为1000行或2000行,我必须在某处进行配置。
它将在每1000或2000行之后使用自动提交更新循环中的百万行。此功能在sqlloader中可用。我想知道oracle中是否也有类似的功能。
答案 0 :(得分:6)
没有。您不能要求Oracle逐步提交单个SQL语句正在执行的工作。这会违反ACID合规性的原子性部分,因此对于允许关系数据库来说这将是一件非常糟糕的事情。这样做意味着如果数据库失败或者在处理N行后语句失败,您将无法知道哪些N行已被处理。这样做意味着其他用户可能会看到部分完整的数据导致他们的报告不正确,并且他们的查询可能会返回误导性结果。
当然,您可以编写自己的自定义逻辑,批量更新行。然而,这通常是一个坏主意。运行正在进行临时提交的进程需要更长时间,可能更长。它需要编写代码以确保该过程是可重入的(也就是说,它可以在服务器发生故障时从中断处继续,而不会尝试重新更新已更新和已提交的行或在最少不要将数据更新为其他值。这将导致更新在服务器上生成更多UNDO
和REDO
。这将要求使用数据的每个进程都知道他们可能正在阅读它在处理UPDATE
语句的过程中。它增加了ORA-01555错误的风险。通常没有必要进行临时提交 - 缺点很少,非常非常值得。
答案 1 :(得分:1)
是。您可以使用DBMS_PARALLEL_EXECUTE执行此操作。
该包显然是为了并行执行,但它也在每个“块”之后提交。您可以将chunk_size
设置为1000或2000行,并将parallel_level
设置为0以串行运行。
这是一个简单的例子:
create table table1(a number);
insert into table1 select level from dual connect by level <= 100000;
commit;
begin
dbms_parallel_execute.create_task('update_table1');
dbms_parallel_execute.create_chunks_by_rowid(
task_name => 'update_table1',
table_owner => user,
table_name => 'TABLE1',
by_row => true,
chunk_size => 1000
);
dbms_parallel_execute.run_task(
task_name => 'update_table1',
sql_stmt => 'update table1 set a = 5 where rowid between :start_id and :end_id',
language_flag => dbms_sql.native,
parallel_level => 0);
end;
/
尝试在中途终止查询或会话。您只能看到某些更改已提交,您可以使用dba_parallel_execute_chunks
跟踪块状态。
但,我同意Justin Cave和Wolf的说法,这个功能几乎总是一个坏主意。
答案 2 :(得分:-3)
语法 AUTOCOMMIT {ON |关闭} 描述 打开或关闭连接的自动提交模式。 JDBC指定默认自动提交模式为ON。某些类型的处理要求自动提交模式为OFF。有关自动提交的信息,请参阅Java DB Developer's Guide。
如果事务未完成时自动提交模式从关闭更改为打开,则在当前事务提交时提交该工作,而不是在打开自动提交时提交。在未完成事务时启用自动提交之前使用提交或回滚,以便在返回自动提交模式之前完成所有先前的工作。
Example
ij> autocommit off;
ij> DROP TABLE menu;
0 rows inserted/updated/deleted
ij> CREATE TABLE menu (course CHAR(10), item CHAR(20), price INT);
0 rows inserted/updated/deleted
ij> INSERT INTO menu VALUES ('entree', 'lamb chop', 14),
('dessert', 'creme brulee', 6),
('appetizer', 'baby greens', 7);
3 rows inserted/updated/deleted
ij> commit;
ij> autocommit on;
ij>