Я понимаю, что ваше приложение, использующее SQLite, невелико, и SQLite имеет свою семантику. Другие решения, опубликованные здесь, вполне могут иметь тот эффект, который вам нужен в этом конкретном случае, но, на мой взгляд, каждое из них, которое я читал до сих пор, в корне неверно и его следует избегать.
В обычной среде проведение транзакции для пользовательского ввода следует избегать любой ценой. Чтобы справиться с этим, если вам необходимо сохранить промежуточные данные, это записать информацию в таблицу операций для этой цели, а затем попытаться записать всю информацию в элементарной транзакции. Удержание транзакций порождает тупики и ночные кошмары в многопользовательской среде.
В большинстве сред вы не можете предполагать, что данные, полученные с помощью SELECT в транзакции, являются повторяемыми. Например
SELECT Balance FROM Bank ...
UPDATE Bank SET Balance = valuefromselect + 1.00 WHERE ...
После ОБНОВЛЕНИЯ значение баланса вполне может быть изменено. Иногда вы можете обойти это, обновив строку (-ы), интересующую вас Банком, сначала в рамках транзакции, так как это гарантированно блокирует строку, предотвращая дальнейшее изменение значения, пока ваша транзакция не будет завершена.
Однако иногда лучшим способом обеспечения согласованности в этом случае является проверка ваших предположений о содержании данных в предложении WHERE обновления и проверка количества строк в приложении. В приведенном выше примере, когда вы «ОБНОВЛЯЕТЕ Банк», предложение WHERE должно указывать ожидаемое текущее значение баланса:
WHERE Balance = valuefromselect
Если ожидаемый баланс больше не совпадает, то и условие WHERE не выполняется - UPDATE ничего не делает, а rowcount возвращает 0. Это говорит о том, что возникла проблема с параллелизмом, и вам нужно снова запустить операцию, когда что-то другое не пытается изменить ваши данные одновременно.