Felhasználói eszközök

Eszközök a webhelyen


oktatas:adatbazis-kezeles:tranzakcio

< Adatbázis-kezelés

Tranzakció

  • Szerző: Sallai András
  • Copyright © Sallai András, 2014
  • Licenc: GNU Free Documentation License 1.3

Fogalom

Inkonzisztens

Egymásnak ellentmondó adatok

Osztott erőforrások

Az erőforrásainkat szeretjük megosztani több felhasználó között, a gazdaságosabb, hatékonyabb működés érdekében. Egy erőforrás használata konfliktushoz vezethet, ha egyszerre akarja használni két vagy több felhasználó. Az adatbázisainkat általában egyszerre többen használjuk, az egyes adatbázis műveletek szintén konfliktusba kerülhetnek egymással.

ACID elvek

  • Atomicity - A műveletek egybe tartoznak. Vagy mindent végrehajtok vagy semmit.
  • Consistency - Konzisztens állapot - műveletek előtt naplózás
  • Isolation - Egy művelet nem függ másoktól
  • Durability - Tartósság - az elvégzett műveletek eredménye legyen tartós

A tranzakcióról

Egyben kezelt műveletsor, amelyre teljesülnek az ACID elvek.

Az adatok védelme érdekében a tranzakciókezelés során két feladat van:

  • a tranzakciók, korrekt párhuzamos végrehajtása
  • tevékenységek naplózása

Tranzakció példa

A tranzakciók tárgyalásánál gyakran használnak egy banki átutalást példaként:

  1. Megnézzük létezik-e a célszámla
  2. Megnézzük a forrásszámlán van-e elég pénz
  3. Csökkentjük a forrásszámla egyenlegét
  4. Növeljük a célszámla egyenlegét

MySQL tranzakció

Példa:

Legyen a következő két tábla:

CREATE TABLE IF NOT EXISTS `Dolgozok` (
`az` INT(11) NOT NULL,
  `nev` VARCHAR(28) DEFAULT NULL,
  `anyja_neve` VARCHAR(23) DEFAULT NULL,
  `telepules` VARCHAR(20) DEFAULT NULL,
  `lakcim` VARCHAR(46) DEFAULT NULL,
  `fizetes` DOUBLE DEFAULT NULL,
  `szuletes` DATE DEFAULT NULL,
  `jutalom` DOUBLE DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `Naplo` (
`az` INT(11) NOT NULL,
  `telepules` VARCHAR(100) COLLATE utf8_hungarian_ci NOT NULL,
  `osszeg` DOUBLE NOT NULL,
  `megjegyzes` text COLLATE utf8_hungarian_ci NOT NULL,
  `datum` DATE NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;

Feltöltjük, a Dolgozok táblát, úgy hogy legyen miskolci dolgozó, majd a következő SQL utasítást adjuk ki:

START TRANSACTION;
 
SELECT @A:=SUM(fizetes) 
FROM `Dolgozok`
WHERE telepules="Miskolc";
 
INSERT INTO Naplo (osszeg, telepules, datum)
VALUES (@A, "Miskolc", "2014-09-23");
 
commit;

Izolációs szintek

Izolációs szintek a MySQL tranzakciókban

READ UNCOMMITED

Olyan adatokat is olvashatunk, amelyek még nincsenek rögzítve. Piszkos olvasás. A tranzakció vége előtt már olvashatók a nem rögzített adatok.

READ COMMITED

Olvasáskor mindig a már rögzített (commitelt) eredményt kapjuk. Ha fut egy tranzakció ami már változtatott az általunk kívánatos sorokon, akkor mi a régi eredményeket kapjuk. Ha sokan írják az adatbázist, itt lassulás következhet be, más folyamatok arra várnak, hogy az egész tábla frissítése befejeződjön.

Előforulhat a Phantom read és Non-repeatable reads hiba.

A Phantom read jelentése a következő: Előfordulhat, hogy két lekérdezés lefut és más eredményt adnak.

A Non-repeatable reads azt jelenti, hogy egy tranzakció még nem fejeződött be, amikor egy másik már megváltoztatta az olvasott adatokat.

Alapértelmezett szint MS SQL Server esetén.

REPEATABLE READ

Alapértelmezett szintje az InnoDB tábláknak. Csak rögzített rekordokat olvasunk. Vagyis nem várunk a teljes tábla frissítésére, ami már rögzített rekord az olvasható is.

Előfordulhat a Phantom read hiba.

SERIALIZABLE

Más tranzakció nem frissíthet, nem nézhet a táblába, amíg véget nem ér egy tranzakció. Olyan mint a zárolt (LOCK) tábla.

InnoDB és más rendszerek

Az InnoDB mind a négy szintet támogatja. De vigyázzunk konvertáláskor, mert más adatbázis-kezelők esetleg nem támogatják mind a négy szintet.

Pl.:

  • PostgreSQL
    • alapértelmezett: REPEATABLE READ
    • támogatja: REPEATABLE READ and SERIALIZABLE
  • Oracle
    • alapértelmezett: READ COMMITTED
    • támogatott: READ COMMITTED, SERIALIZABLE és a nem szabványos READ ONLY)
  • MS SQL
    • READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SNAPSHOT , SERIALIZABLE

Izolációs szint beállítása

A my.cnf állományban a [mysqld] szakaszban állíthatjuk:

[mysqld]
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}

Vagy egy SQL paranccsal is megadhatjuk amit szeretnénk:

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
                       {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

A tranzakciós szintet mindig a tranzakció megkezdése előtt kell beállítani.

Ellenőrzés:

SELECT @@GLOBAL.tx_isolation, @@tx_isolation

Izolációs szint tesztelése

Teszttábla létrehozása

CREATE TABLE tabla1 (
  az INT PRIMARY KEY AUTO_INCREMENT,
  mezo1 INT,
  mezo2 INT,
  mezo3 INT 
  );

Feltöltjük tartalommal:

INSERT INTO tabla1(mezo1, mezo2, mezo3)
SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3;

Read Uncommitted

Elindítunk egy tranzakciót, de a befejezés előtt várunk 20 percet.

START TRANSACTION;   
UPDATE tabla1 SET mezo1 = 2;   
SELECT sleep(20);   
ROLLBACK;

A set transaction utasítás egy select erejéig beállítja a read uncommitted izolációs szintet.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;   
SELECT * FROM tabla1;

Read Committed

Elindítunk egy tranzakciót, de a befejezés előtt várunk 20 percet.

START TRANSACTION;   
UPDATE tabla1 SET mezo1 = 2;   
SELECT sleep(20);   
ROLLBACK;

A set transaction utasítás egy select erejéig beállítja a read uncommitted izolációs szintet.

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;   
SELECT * FROM tabla1;
oktatas/adatbazis-kezeles/tranzakcio.txt · Utolsó módosítás: 2019/08/15 20:50 szerkesztette: admin