Changes between Version 1 and Version 2 of Transakcii


Ignore:
Timestamp:
02/08/26 21:17:19 (2 weeks ago)
Author:
213192
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Transakcii

    v1 v2  
    11== Трансакции
    22
    3 Трансакција е логичка целина од повеќе операции над базата на податоци. Тие располагаат со повеќе својства:
    4 
    5 * -атомичност: или сите операции ќе се извршат(commit) или ниедна нема да се зачува(rollback). Пример ако внесеме нов играч и во истата трансакција внесуваме статистики за тој играч, не сакаме да имаме статистики без играч
    6 
     3Трансакција е логичка целина од повеќе операции над базата на податоци. Тие располагаат со повеќе својства (ACID својства):
     4
     5* атомичност: или сите операции ќе се извршат(commit) или ниедна нема да се зачува(rollback). Пример ако внесеме нов играч и во истата трансакција внесуваме статистики за тој играч, не сакаме да имаме статистики без играч
     6
     7* конзистентност: многу е важно секоја трансакција да го одржува интегритетот на базата, односно секој запис да ги почитува ограничувањата на базата. На пример, во базата, играчот мора да има валиден тим, во спротивно нема да се изврши трансакцијата.
     8
     9* изолација: трансакциите се изолирани една од друга. Така, во PostgreSQL нивото на изолација најчесто е READ COMMITTED, што значи дека една трансакција гледа само податоци кои се веќе извршени. Пример: додека една трансакција ажурира вредност, друга не може да види полу-променети податоци.
     10
     11* трајност: најважно од се е промените да се запишат и зачуваат по извршувањето. За тоа PostgreSQL користи WAL (ќе го споменеме понатаму). Ако серверот се рестартира, податоците нема да бидат изгубени по извршена трансакција.
     12
     13=== Изолациони нивоа
     14
     15Изолационите нивоа дефинираат колку една трансакција ќе биде изолирана од другите. Во PostgreSQL постојат:
     16
     17* READ UNCOMMITTED: трансакцијата  може да чите и непотврдени промени (dirty reads)
     18
     19* READ COMMITTED: трансакцијата чита само комитирани промени
     20
     21* REPEATABLE READ: сите SELECT операции во една трансакција гледаат исти податоци
     22
     23* SERIALIZABLE: највисоко ниво на изолација - трансакциите се случуваат една по друга
     24
     25READ COMMITTED vs SERIALIZABLE
     26
     27{{{
     28BEGIN;
     29
     30 
     31
     32SELECT highest_market_value_in_eur
     33
     34FROM players
     35
     36WHERE player_id = 26;
     37
     38UPDATE players
     39
     40SET highest_market_value_in_eur = 7000000
     41
     42WHERE player_id = 26;
     43
     44 
     45
     46COMMIT;
     47
     48SELECT highest_market_value_in_eur
     49
     50FROM players
     51
     52WHERE player_id = 26;
     53
     54 
     55
     56 
     57
     58COMMIT;
     59}}}
     60
     61Истата трансакција гледа различна вредност, ова е дозволено во READ COMMITTED
     62
     63{{{
     64BEGIN ISOLATION LEVEL SERIALIZABLE;
     65
     66 
     67
     68SELECT highest_market_value_in_eur
     69
     70FROM players
     71
     72WHERE player_id = 26;
     73
     74 
     75
     76UPDATE players 
     77
     78SET highest_market_value_in_eur = 9000000 
     79
     80WHERE player_id = 26; 
     81
     82COMMIT; 
     83
     84 
     85
     86 
     87
     88SELECT highest_market_value_in_eur
     89
     90FROM players
     91
     92WHERE player_id = 26;
     93
     94 
     95
     96 
     97
     98COMMIT;
     99}}}
     100
     101Serializable нема non-repeatable read, конзистентност на ниво на трансакција.
     102
     103=== Deadlocks
     104
     105Deadlock настанува кога две или повеќе трансакции меѓусебно се блокираат, најчесто поради тоа што едната чека ресурс што го содржи другата. Најчеста причина за појавување на deadlock е неконзистентен редослед на заклучување на редови. 
     106
     107{{{
     108BEGIN; 
     109
     110 
     111
     112SELECT * FROM players WHERE player_id = 10 FOR UPDATE; 
     113
     114 
     115
     116SELECT * FROM players WHERE player_id = 20 FOR UPDATE; 
     117
     118 
     119
     120COMMIT;
     121
     122BEGIN;
     123
     124 
     125
     126SELECT * FROM players WHERE player_id = 20 FOR UPDATE;
     127
     128 
     129
     130SELECT * FROM players WHERE player_id = 10 FOR UPDATE;
     131
     132 
     133
     134COMMIT;
     135}}}
     136
     137Овие две трансакции ажурираат два играчи, но во различен редослед. PostgreSQL детектира deadlock, но една многу добра карактеристика на PostgreSQL e тоа што има deadlock detector при што автоматски прекинува една трансакција. 
     138
     139Како да избегнеме deadlock?
     140
     141{{{
     142SELECT * FROM players
     143
     144WHERE player_id IN (10, 20)
     145
     146ORDER BY player_id
     147
     148FOR UPDATE;
     149}}}
     150
     151Deadlock состојбите претставуваат сериозен предизвик во системи со висока конкурентност. PostgreSQL користи автоматска детекција на deadlock, при што една од трансакциите се прекинува за да се избегне застој на системот. Примената на конзистентен редослед на заклучување и краткотрајни трансакции значително го намалува ризикот од вакви ситуации.
     152
     153=== Locks и MVCC во PostgreSQL
     154
     155Во системи со повеќе истовремени корисници, базата на податоци мора да обезбеди конзистентност и изолација на податоците, без притоа да се жртвуваат перформансите. PostgreSQL го решава овој проблем преку комбинација на механизми за заклучување (locking) и Multi-Version Concurrency Control (MVCC).
     156
     157Во овој дел се прикажува разликата помеѓу table-level locking, row-level locking и MVCC, со практични примери кои покажуваат како различните пристапи влијаат врз конкурентноста, блокирањето и видливоста на податоците помеѓу трансакции.
     158
     159Table-level locking
     160
     161* целата табела е заклучена
     162* други трансакции чекаат, дури и ако работат на друг ред
     163* многу лоша конкурентност
     164
     165{{{
     166BEGIN;
     167
     168LOCK TABLE players IN ACCESS EXCLUSIVE MODE;
     169
     170-- табелата е целосно заклучена
     171
     172SELECT * FROM players; (ACCESS EXCLUSIVE е најсилен lock)
     173}}}
     174
     175Row-level locking
     176
     177* многу подобра верзија од table-level locking
     178* се заклучува само конкретниот ред, другите редови се слободни
     179
     180{{{
     181BEGIN;
     182
     183SELECT * FROM players WHERE player_id = 1 FOR UPDATE;
     184
     185-- само редот со id=1 е заклучен
     186
     187SELECT * FROM players WHERE player_id = 2;
     188
     189-- работи нормално
     190
     191UPDATE players SET highest_market_value_in_eur = highest_market_value_in_eur - 100 WHERE player_id = 1;
     192
     193-- чека, редот е заклучен
     194}}}
     195
     196MVCC(Multi-Version Concurrency Control)
     197
     198* наместо locks, PostgreSQL креира нови верзии на редиците (помалку блокирања)
     199
     200{{{
     201-- Session 1
     202BEGIN;
     203
     204UPDATE players
     205SET market_value_in_eur = market_value_in_eur - 5000000
     206WHERE player_id = 19054;
     207
     208-- трансакцијата е започната, но не е направен COMMIT
     209}}}
     210
     211{{{
     212-- Session 2
     213SELECT market_value_in_eur
     214FROM players
     215WHERE player_id = 19054;
     216-- Session 2 ја гледа старата вредност
     217}}}
     218
     219{{{
     220-- Session 1
     221COMMIT;
     222}}}
     223
     224{{{
     225-- Session 2
     226SELECT market_value_in_eur
     227FROM players
     228WHERE player_id = 19054;
     229-- сега Session 2 ја гледа новата вредност
     230}}}
     231
     232MVCC е одличен бидејќи нема блокирање на SELECT операции, нема dirty reads и има висока конкурентност.