Transaction Isolation Levels With PostgreSQL as an example

Поділитися
Вставка
  • Опубліковано 6 вер 2024
  • In this video, Boris Strelnikov will explain which transaction isolation levels exist in databases and what you should be aware of as a developer.
    You will see dirty read, lost update, non-repeatable read, phantoms and serialization anomaly - most of them demoed inside PostgreSQL database.
    You can hire Boris as your programming mentor or get a consultation from him here: mkdev.me/en/me...
    Check out mkdev dispatch, bi-weekly newsletter about DevOps and Cloud Native - mkdev.me/dispatch
    DevOps Accents is our monthly podcast, where 3 mkdev founders chat about DevOps, Cloud and Life: mkdev.me/podcast
    At mkdev we provide all range of IT services, from trainings and workshops to audit and consulting.
    Check out our website: mkdev.me/en/b or contact us at team@mkdev.me
    #databases #rdbms #postgresql #transactionisolation #acid

КОМЕНТАРІ • 29

  • @daviddarfdas
    @daviddarfdas Місяць тому

    Amazing video. Having examples from the actual database system makes the topic so much easier to grasp. Thank you.

  • @bohdankolomiiets1108
    @bohdankolomiiets1108 2 роки тому +18

    Thanks for video.
    It seems that example of lost updated is incorrect.
    In both sessions you update table orders setting total to 100 + 1. You can apply this update as many time as you want and you will get 101 value of total column. Maybe you wanted to incremet value like "total = total + 1" ?

    • @risentveber
      @risentveber 2 роки тому +2

      Nice notice! Yeah, that's why the first select is shown because the update is based on "what is read into local memory". To explicitly emphasize it, I wrote it as "total = 100 + 1" where 100 was gotten from the select result. If there was no such phenomenon, it would be incremented 2 times or only the first would succeed and the second would fail. In this particular example, one could use `UPDATE orders SET total=total+1 WHERE id = 1` to achieve the desired result, but the main idea was to show a more general case when one explicitly read something and update it based on what it read(it may depend on several fields and there is no such atomic update in that case).

  • @olmanmora21
    @olmanmora21 2 роки тому +4

    This has been incredibly helpful, thanks for the short and concise explanation.

  • @Boyarsskiy
    @Boyarsskiy 10 місяців тому

    The best, full, clear and shortest explanation I've ever seen. Thanks!

  • @josephmbimbi
    @josephmbimbi 10 місяців тому +3

    Nice video, but I didn't understand the serialization anomaly example

  • @Neykuratick
    @Neykuratick Рік тому +2

    Why did you use the same data in the lost update example?
    Wouldn't the example be more accurate if you've used 101 in the first transaction and 102 in the second one?

  • @mitsukiorichimaru4511
    @mitsukiorichimaru4511 3 роки тому +2

    wait, i thought all transactions in 'serializable isloation level' are executed in serial manner, i.e; one after the other., trading off the concurrency(parallel or interleaved execution). But the last example is opposite to my understanding. Moreover transaction t2 where it operates on 'failed' items puts a range lock, stopping other transactions to operate on the same data rows coz to not allow 'non-repeatable' and 'phantom' reads phenomena, but the transaction 1 was able to insert a new row with 'failed' status row. how ? This messed up my understanding of locks and isolation levels. haha. Please clarify. Thanks

    • @risentveber
      @risentveber 3 роки тому +4

      Serializable transactions is guaranteed(if successfully committed) to produce the same effect as running them one at a time in some order. But actually they can be run in concurrent manner.

  • @Hillerob
    @Hillerob 2 роки тому +1

    Hello comrad, whu there are no videos on russian:(
    I've detected what's your native language on first minute.

  • @aleksey6639
    @aleksey6639 Рік тому

    Не понятно почему на уровне "Rad committed" будет возникать "Lost update", ведь на этом уровне пока мы не закоммитим одну из транзакций другая не будет продолжена, т.к. будет блокировка на строке. И после того, как мы закоммитим первую, другая увидит изменения и все будет ожидаемо, ничего не пропадет. Или я чего-то не понимаю?

    • @Boyarsskiy
      @Boyarsskiy 10 місяців тому

      Возьмём пример: инкрементим какое-то значение на уровне приложения. Допустим изначально в БД было 100. По бизнес-логике после двух инкрементов двумя транзакциями должно быть 102. Обе транзакции первым запросом считали одно и то же значение, читать одновременно им никто не мешает, далее на уровне приложения сделали инкремент к одному и тому же значению которое они считали (100 + 1 = 101) и пошли из приложения вторым запросом обновлять одну и ту же строку. При их успешном обновлении мы в БД получим 101, а не 102 как хотелось бы, это и есть потерянное обновление.
      На уровне READ COMMITTED обновление сначала пройдёт от той транзакции которая запустила обновление первой, а следующая транзакция подвиснет и будет ждать её завершения. Дождавшись, тоже сделает своё обновление. В итоге в БД будет не 102, а 101. И никаких ошибок на уровне БД и приложения мы не увидим, зато потеряли один инкремент.
      Вот если бы стоял уровень REPEATABLE READ, то вторая транзакция тоже бы подвисла, но после завершения первой транзакции кинула бы исключение и откатилась, так как обнаружила бы что то поле которое она хочет изменить было изменено и закомичено другой транзакцией. Зато приложение знает (если хорошо написано), что нужно сделать ретрай и после успешного его завершения будет затем 102. Либо может вернуть пользователю ошибку и попросить сделать действие заново, это уже от архитектуры зависит.

    • @aleksey6639
      @aleksey6639 10 місяців тому +1

      @@Boyarsskiy В некоторых СУБД это может и так, но в PostgreSQL это работает иначе - после снятия блокировки вторая транзакция перечитывает значение (изначально она считала 100, затем наткнулась на блокировку, блокировка снята, снова считывает данные (уже 101), делает свой инкремент и в итоге в ячейке будет 102) => Lost update не будет.

    • @Boyarsskiy
      @Boyarsskiy 10 місяців тому

      А вы проверьте на практике. Я проверил и описал как было.

    • @aleksey6639
      @aleksey6639 10 місяців тому

      ​@@BoyarsskiyДа, сейчас еще раз проверил, Lost update отсутствует. Судя по всему что-то в наших инстансах разное. Быть может вы делаете это с Read Uncommitted?
      Я также нашел описание работы этих уровней в книге Е.П. Моргунова "PostgreSQL Основы языка SQL" от 2018 года. Там на странице 261 (глава 9.3 Уровень изоляции Read Committed) написано следующее: "Теперь обратимся к уровню изоляции Read Committed. Именно этот уровень установлен в PostgreSQL по умолчанию. Мы уже показали, что на этом уровне изоляции не допускается чтение незафиксированных данных. А сейчас покажем, что на этом уровне изоляции также гарантируется отсутствие потерянных обновлений, но возможно неповторяющееся чтение данных"

    • @Boyarsskiy
      @Boyarsskiy 10 місяців тому

      @@aleksey6639 Read Uncommitted в Postgres нет, вернее есть. но он точно такой же как и Read Committed. Это же в данном видео тоже показано.

  • @nc2809
    @nc2809 3 роки тому +2

    Нихрена не понятно, почему на сводной таблице (05:35) на пересечении уровня "Repeatable read" и феномена "Non-repeateble read" стоит плюсик. Где логика? Плюсик говорит, что феномен возможен получается на этом уровне, но это не так, в этом как раз смысл этого уровня, чтобы исключать неповторяемое чтение, или я что-то не понял? Также ты говоришь, что грязное чтение невозможно ни на одном уровне, а тут плюсики везде. Т.е. инверсия как бы.

    • @nc2809
      @nc2809 3 роки тому

      В то же время, если плюсик рассматривать как то, от чего мы защищены, то не понятно, почему мы защищены от фантомов на уровне изоляции "repeatable read", хотя от них защита есть только на уровне serializable

    • @risentveber
      @risentveber 3 роки тому

      @@nc2809 потому что для PostgreSQL поведение уровней изоляции определено именно так - см www.postgresql.org/docs/13/transaction-iso.html

    • @nc2809
      @nc2809 3 роки тому +1

      @@risentveber большое спасибо, разобрался

  • @gatocode316
    @gatocode316 3 роки тому +1

    nice bro!

  • @artemiosdev
    @artemiosdev 3 роки тому +2

    Крутой ролик, очень полезная инфа, спасибо👍😎

  • @wotok7
    @wotok7 3 роки тому +5

    Норм. И английский попрактиковал )