2014-11-07 3 views
6

Я пытаюсь преобразовать некоторые необработанные вызовы DBI в DBIx :: Class. Я иногда натыкаться что-то вроде:Как увеличить столбец с помощью DBIx :: Class?

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

Есть ли способ действительно есть DBIx :: Class выполнить именно такой запрос? Я не хочу, чтобы сделать что-то вроде:

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

, потому что это состояние гонки есть если несколько процессов пытаются сделать то же самое.

Я мог бы обойти это с помощью какой-то блокировки на уровне базы данных, но мне это кажется хуже, чем просто с использованием исходного запроса. В основном я просто хочу знать, есть ли чистый способ использования DBIC для этого или если я просто буду продолжать использовать необработанные вызовы DBI здесь.

+0

Я предполагаю, что вы имели в виду '$ строка -> {bar} ', а не' $ row-> bar() ' – TLP

+0

Приращения на 1 обычно для счетчиков. Какие условия гонки вы испытываете на этом поле? –

+0

@TLP Я имел в виду $ row-> bar(), где $ row - объект результата DBIC. – oalders

ответ

3

использование раствор от @ ThisSuitIsBlackNot своего комментария, но заменить update_all с update:

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

Это приведет к в одном операторе UPDATE. (Пояснение:.. update_all работает по призванию update на каждой строке в ResultSet, включая такие вещи, как DBIC триггеров, поэтому он должен первым получать строки update на ResultSet выполняет баребонов SQL UPDATE)

0

Будет использовать DBIx :: Class :: Storage :: TxnScopeGuard help? Вы можете обернуть блок кода в транзакции, как этого

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

В этом случае он не полностью решает проблему, возникающую во время чтения, а также время записи. Я думаю, комментарий @ThisSuitIsBlackNot - это, пожалуй, самый чистый способ сделать это. – oalders

+0

@ ужины - да, спасибо. –