Ну как бы и без транзакций можно обходиться. Например использовать поле version, которое прибавляется каждый раз при при update.
Если вся работа с данными сводится к их добавлению, то транзакции и не нужны.
Но если присутствует цикл select/update, да еще и в несколько потоков, то рано или поздно данные повредятся.
Простой случай, возьмем поле debit. Попробуем его увеличивать в несколько потоков без транцакций в цикле -
select debit from mytable where ID=10
, программно прибавляем единичку к полученному debit, затем делаем
update mytable set debit=11 where ID=10
. Результат приятно удивит.
Также можно обойтись и без транзакций (точнее использовать так называемые "оптимистические блокировки"), если с полем debit считывать, например, поле version -
select debit, version as oldversion from mytable where ID=10
. Тогда update будет выглядеть примерно так
update mytable set debit =11, version=version+1 where ID=10 and version=oldversion
. Но при этом придется всегда проверять, изменили ли мы данные или нет.
ЗЫ. По просьбам трудящихся, про оптимистические блокировки -
https://ru.wikipedia.org/wiki/Блокировка_(СУБД)