wiki:AdvancedApplicationDevelopment

Version 3 (modified by 223306, 6 days ago) ( diff )

--

Advanced Application Development

Transactions

Во BiblioPremium се користат трансакции кај сценарија во кои една корисничка акција предизвикува повеќе поврзани промени во базата. На овој начин се обезбедува сите операции да бидат успешно извршени како една целина или, во случај на грешка, сите промени да бидат поништени.

Трансакција при купување книга

При купување книга се извршуваат повеќе операции во рамки на една трансакција:

  1. Се проверува цената и достапната количина на книгата.
  2. Се креира нова нарачка во табелата naracki.
  3. Се додава ставката во табелата sodrzi.
  4. Се евидентира плаќањето во табелата plakanja.
  5. Се намалува количината на залиха во табелата knigi.

Доколку сите операции се успешни се повикува:

conn.commit()

Доколку настане грешка, се повикува:

conn.rollback()

со што се поништуваат промените направени во рамки на трансакцијата.

Дел од имплементацијата:

try:
    cursor.execute("""
        INSERT INTO project.naracki
            (datum, status, vkupna_cena, korisnik_id)
        VALUES
            (CURRENT_TIMESTAMP, %s, %s, %s)
        RETURNING naracka_id;
    """, ("ZAVRSENA", vkupna_cena, session["korisnik_id"]))

    naracka_id = cursor.fetchone()[0]

    cursor.execute("""
        INSERT INTO project.sodrzi
            (naracka_id, kniga_id, kolicina, edinechna_cena)
        VALUES (%s, %s, %s, %s);
    """, (naracka_id, kniga_id, kolicina, cena))

    cursor.execute("""
        INSERT INTO project.plakanja
            (datum, iznos, nacin_na_plakjanje, status, naracka_id)
        VALUES
            (CURRENT_TIMESTAMP, %s, %s, %s, %s);
    """, (vkupna_cena, "KARTICKA", "USPESNO", naracka_id))

    cursor.execute("""
        UPDATE project.knigi
        SET kolicina_na_zaliha = kolicina_na_zaliha - %s
        WHERE kniga_id = %s;
    """, (kolicina, kniga_id))

    conn.commit()

except Exception as e:
    conn.rollback()

Трансакцијата беше тестирана преку апликацијата со успешно купување на книгата „Ikigai“. Беше креирана нарачка #16 со количина 1 и вкупна цена 750 денари. Нарачката беше успешно прикажана и во историјата „Мои нарачки“.

Трансакција при зачувување кориснички преференции

Трансакција се користи и при промена на корисничките преференции. Старите жанровски и категориски преференции се бришат, а потоа се внесуваат новоизбраните вредности.

Доколку сите операции се успешни се извршува commit(), а при грешка rollback(). На овој начин корисникот не може да остане со делумно ажурирани преференции.

Database Connection Pooling

За управување со конекциите кон PostgreSQL базата е имплементиран connection pool со psycopg2.pool.

При стартување на апликацијата се креира pool со минимално 1 и максимално 10 конекции:

from psycopg2 import pool

db_pool = pool.SimpleConnectionPool(
    1,
    10,
    host="localhost",
    port=tunnel.local_bind_port,
    database=DB_NAME,
    user=DB_USER,
    password=DB_PASSWORD
)

За земање и враќање конекција се користат функции:

def get_db_connection():
    return db_pool.getconn()

def release_db_connection(conn):
    db_pool.putconn(conn)

Пред пристап до базата, потребната конекција се зема од pool:

conn = get_db_connection()
cursor = conn.cursor()

По завршување на работата cursor-от се затвора, а конекцијата се враќа во pool:

cursor.close()
release_db_connection(conn)

Овој пристап се користи во рутите кои пристапуваат до базата, вклучувајќи пребарување и приказ на книги, препораки, омилени книги, нарачки, преференции и административните функционалности.

Connection pool-от беше успешно тестиран при стартување и користење на апликацијата. Апликацијата успешно зема конекции од pool-от, извршува операции кон базата и ги враќа конекциите за повторна употреба.

Заклучок

Во оваа фаза апликацијата е надградена со трансакциско извршување на операции кои бараат атомарност и со connection pooling за поефикасно управување со конекциите кон PostgreSQL базата.

Note: See TracWiki for help on using the wiki.