wiki:Трансакции

Version 30 (modified by 183175, 15 hours ago) ( diff )

--

Трансакции

Употреба на 'Трансакции' соодветно проектот

Трансакциите може да се состојат од една операција за читање, запишување, бришење или ажурирање
или комбинација од нив. Трансакцијата во SQL се низа од една или повеќе SQL активности извршени како една функција.Главната идеја зад трансакцијата е дека сите промени направени во неа треба или да бидат целосно успешни или целосно да се поништат во случај на неуспех.
Во случај на грешка, враќањето осигурува да не се зачуваат делумни промени.

Како што знаеме, трансакциите треба да ги содржат следниве 4 аспекти познати како ACID :
-> Atomicity
Тоа би значело резултатот од трансакцијата може да биде или целосно успешен или целосно неуспешен.
Целата трансакција мора да се врати назад ако еден дел од неа не успее.
-> Consistency
Трансакцијата ја претвора базата од една валидна состојба во друга валидна состојба.
Правилата и ограничувањата на базата секогаш остануваат запазени.
-> Isolation
Секоја трансакција се извршува како да е единствената во системот.
Паралелните трансакции не си влијаат меѓусебно додека се извршуваат.
На тој начин се гарантира точноста на податоците.
-> Durability
Откако трансакцијата ќе биде потврдена, промените се трајно зачувани.
Дури и при пад на системот, податоците остануваат зачувани.

Исто така, да не заборавиме дека трансакциите се карактеристички по опфаќање на следниве 4 команди :
BEGIN TRANSACTION -> COMMIT -> ROLLBACK -> SAVEPOINT


Поради тоа, на страната app.js, го додаваме следново:
-> трансакцијата ја започнуваме со await client.query('BEGIN');
на овој начин сите операции кои следат ќе бидат извршени во контекст на една трансакција
-> ако сите операции во тек на трансакција бидат успешни,
правиме COMMIT со await client.query('COMMIT');
-> доколку се случи грешка во било кој дел од процесот,
сите промени ќе се поништат со await client.query('ROLLBACK');
-> ке имаме функционален SAVEPOINT и подобрена заштита од грешки во трансакциите, доколку по внесување нов customers, ако има грешки во transactions
враќаме ROLLBACK TO SAVEPOINT customer_added наместо целосен ROLLBACK.
Ако се е во ред, правиме COMMIT и зачувуваме во база,
а ако има некоја друга грешка, правиме целосен ROLLBACK

Соодветно темата и целта на мојот проект,трансакциите би требало да бидат имплементирани на овој начин:
-> Да можам да направам нарачка и намалам залиха во ист процес
-> Гаранција дека сите чекори во процесот ќе се извршат успешно или воопшто нема да се извршат
-> Можност за враќање на промените ако настане грешка

Update

Atomicity

Како што веќе кажавме, за еден успешен Atomicity потребно е имплементација на неколку клучни точки.
Користам BEGIN на почеток, потоа COMMITако помине успешно, и ROLLBACKако има грешка.
Ако некој чекор не успее, во catchфаќаме грешки, повикуваме ROLLBACK,
и трансакцијата се поништува а притоа ниту еднапромена не се зачувува.
Сега по поставам реални примери од фајлот app.js каде ги имам употребено истите за да докажеме Atomicity :

Пример 1 : /order API
Првин трансакцијата почнува со

await client.query("BEGIN");


Потоа ги правам сите операции (провери, внеси, ажурирај залиха ...)
Ако некаде има грешка, се отфрла целата операција, и за крај :

await client.query("ROLLBACK");


Доколку сите операции и обиди поминат успешно, се извршува :

await client.query("COMMIT");


Пример 2 : Залиха
Сега ке видиме еден пример како што гласи правилото, трансакција мора да се врати назад ако еден дел од неа не успее.
Ако залихата за некој производ и големина фали,односно нема залиха, фрли грешка:

if (currentStock < item.quantity) {
  throw new Error(`Недоволна залиха за продукт ${item.product_name} (${item.size})`);
}


Ова е пример каде во catch ке дојде некоја грешка и ке направи ROLLBACK

await client.query("ROLLBACK");


Пример 3 : /order endpoint
Овде имам употреба на BEGIN ,COMMIT и ROLLBACK.

const client = await db.pool.connect();
try {
  await client.query("BEGIN");
  // ... сите останати потребни чекори ...
  await client.query("COMMIT");
} catch (err) {
  await client.query("ROLLBACK");
} finally {
  client.release();
}


Пример 4 : Try/catch
Секој чекор во процесот се наоѓа во блок try, па да видиме пример за ажурирање на залиха :

await client.query(
  "UPDATE stock SET quantity = quantity - $1, updated_at = NOW() WHERE id_stock = $2",
  [deductQty, stockRow.id_stock]
);

Кога овој момент нема да успее, ке премине во блок catch.

Note: See TracWiki for help on using the wiki.