如何使用DBIx :: Class增加列?

时间:2014-11-07 18:10:18

标签: sql perl dbix-class

我正在尝试将一些原始DBI调用转换为DBIx :: Class。我偶尔遇到类似的事情:

UPDATE 'foo' SET bar = bar + 1 WHERE ...

有没有办法让DBIx :: Class完全执行这种查询?我不想做类似的事情:

$row->update({ bar => $row->bar() + 1 });

因为如果多个进程试图做同样的事情,就会出现竞争条件。

我可以通过在数据库级别进行某种锁定来解决这个问题,但这对我来说比使用原始查询更糟糕。基本上我只是想知道是否有一种干净的方式使用DBIC来执行此操作,或者我是否应该继续使用原始DBI调用。

2 个答案:

答案 0 :(得分:3)

使用来自@ ThisSuitIsBlackNot评论的解决方案,但将update_all替换为update

$rs->search(...)->update({
    bar => \'bar + 1',
});

这将导致单个UPDATE语句。 (解释:update_all通过在ResultSet中的每一行上调用update来工作,包括DBIC触发器之类的东西,因此它必须首先获取行。在ResultSet上update执行准系统SQL UPDATE 。)

答案 1 :(得分:0)

使用DBIx :: Class :: Storage :: TxnScopeGuard会有帮助吗?您可以在这样的事务中包装您的代码块

my $guard = $schema->txn_scope_guard;
# your increment
$guard->commit;