mysql - 使用perl脚本在mysql中插入时如何使操作原子化

标签 mysql perl

我有一个为客户下订单的 perl 脚本。

2 个表。

table_orders - orderic, customerid, orderdatetime
table_order_details - orderid, productname, Quantity, MRP. Sellprice

插入表格的步骤:

1. insert in table_orders.
2. for each product in shopping cart insert into table_order_details

现在问题是在第一个表中插入之后,

1. It is possible because of some error in input data insertion in second table is not possible and perl returns an error.
2. Few entries done in table 2 too, but now got the error so further entry not possible in table 2 and perl returns an error.

在这两种情况下交易都没有成功完成,那么如何恢复错误发生前数据库中的条目呢?

是否有任何 perl 或 MYSQl wat 可以执行此操作,或者我们需要手动处理它??

最佳答案

使用transactions .

事务允许您隔离对数据库的更改,直到您完成所有更改。当您处理事务时,没有其他人可以看到这些更改,也没有其他人可以更改这些行。然后您提交 事务,其他人可以同时看到您的所有更改。如果出现错误,您可以回滚您在事务中所做的所有更改。

在 Perl 中,使用 DBI,默认是不使用事务的。每个语句都会自动提交。 始终打开事务是一个非常的好主意。您通常在通过设置 AutoCommit 连接到数据库时执行此操作离开。您还需要打开 RaiseError所以数据库错误会自动发生,你不必到处写or die...。然后,由于您不想看到错误两次,请转 PrintError关闭。

my $dbh = DBI->connect(
    'dbi:mysql:...', $user, $pass,
    { AutoCommit => 0, RaiseError => 1, PrintError => 0 }
);

现在您所做的一切都将在一个事务中,并且在您运行 $dbh->commit 之前,其他任何人都看不到您所做的任何事情。将所有工作包装在 eval block 中,以捕获现在 RaiseError 打开时抛出的任何错误。如果出现错误,$dbh->rollback 将丢弃所有部分工作。

eval {
    my $insert_table_orders_sth = $dbh->prepare(
        "INSERT INTO table_orders (...) VALUES (?, ?, ?)"
    );
    $insert_table_orders_sth->execute(@table_orders_values);

    my $insert_table_orders_details_sth = $dbh->prepare(
        "INSERT INTO table_orders_details (...) VALUES (?, ?, ?)"
    );
    for my $product ($cart->products) {
        $insert_table_orders_details_sth->execute($product->values);
    }

    # All done, make the changes visible to everyone else.
    $dbh->commit;
};
if($@) {
    warn "There was a database error: $@";

    # Wipe out anything you did above.
    eval { $dbh->rollback };

    # Do whatever else you might need to cleanup the error.
}

关于mysql - 使用perl脚本在mysql中插入时如何使操作原子化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33029747/

相关文章:

mysql - 如何统计mysql中的非重复列?

如果宽字符错误,Perl 停止打印

perl - 如何强制逻辑或运算符的列表上下文

perl - 在 Perl 中分配和测试定义时理解优先级

python - 查询以使用 mysql 调用与本地数据框中的列匹配的值

不存在的MySQL多插入查询

MySQL - "exact match"针对某个值

perl - 如何在不耗尽 Perl 内存的情况下合并大型未排序文件中的行?

perl - 多行匹配 perl 正则表达式

mysql - 在 Doctrine QueryBuilder 中从 MySQL DATETIME 中检索日期