批处理与单行事务的原子性

Batch processing versus Single row transactions for atomicity

我有两张桌子;一个保存生成的报告记录,另一个更新报告已生成的标志。这个脚本会被调度,SQL已经实现。但是,脚本有两种实现方式:

案例一:

- Insert all the records, then
- Update all the flags,
- Commit if all is well

案例二:

While (there are records)
- Insert a record,
- Update the flag
- Commit if all is well

应该首选哪个,为什么?

案例 1 的事务是针对所有插入,然后是所有更新。全有或全无。我相信这会更快,或者如果与远程数据库的连接不断中断则不会。它只需要很少的客户端处理。但是如果插入中途失败,我们将不得不从顶部重新运行。

案例 2 的一个事务是一个插入、更新。这需要跟踪插入的记录,并更新特定的记录。我将不得不使用占位符,虽然允许数据库缓存 SQL,并重复使用查询执行计划,但我怀疑这会比案例 1 慢,因为有额外的客户端处理。然而,在我们可以假设的不可靠连接上,这看起来是更好的选择。

编辑 2015 年 5 月 11 日 11:31AM

案例 1 片段:

my $sql = "INSERT INTO eval_rep_track_dup\@prod \
            select ert.* \
            from eval_rep_track ert \
            inner join \
            (
                    select erd.evaluation_fk, erd.report_type, LTRIM(erd.assign_group_id, '/site/') course_name \
                    from eval_report_dup\@prod erd \
                    inner join eval_report er \
                    on er.id = erd.id \
                    where erd.status='queue' \
                    and er.status='done' \
            ) cat \
            on ert.eval_id = cat.evaluation_fk \
            and ert.report_type = cat.report_type \
            and ert.course_name = cat.course_name";
    my $sth = $dbh->prepare($sql) or die "Error with sql statement : $DBI::errstr\n";
    my $noterror = $sth->execute() or die "Error in sql statement : " . $sth->errstr . "\n";

...

# update the status from queue to done      
        $sql = "UPDATE eval_report_dup\@prod \
                SET status='done' \
                WHERE id IN \
                ( \
                        select erd.id \
                        from eval_report_dup\@prod erd \
                        inner join eval_report er \
                        on er.id = erd.id \
                        where erd.status='queue' \
                        and er.status='done' \
                )";

        $sth = $dbh->prepare($sql);
        $sth->execute();

eval_rep_track_dup 有 3 个 number、8 个 varchar2 和一个 timestamp 列 eval_report_dup 有 10 number、8 varchar2 和 3 timestamp

好吧,如果由我决定,我会采用后一种方法。主要原因是 server/program 在处理过程中出现故障;您可以轻松地重新开始工作。 祝你好运 pj