import os

import psycopg
from psycopg import errors

# Parameter koneksi mengikuti variabel environment PG* --
# konvensi libpq yang sama dengan psql.
KONEKSI = dict(
    host=os.environ.get("PGHOST", "localhost"),
    port=os.environ.get("PGPORT", "5432"),
    user=os.environ.get("PGUSER", "postgres"),
    dbname=os.environ.get("PGDATABASE", "toko_db"),
)

# Transaksi 1: dua perubahan stok yang harus terjadi bersama-sama
# (pindahan barang dari produk 2 ke produk 1).
with psycopg.connect(**KONEKSI) as conn:
    conn.execute("UPDATE produk SET stok = stok - 2 WHERE id = 2")
    conn.execute("UPDATE produk SET stok = stok + 2 WHERE id = 1")
    # Keluar dari blok `with` tanpa error -> commit otomatis.
print("Transaksi 1 di-commit: stok produk 1 dan 2 berubah bersamaan")

# Transaksi 2: error di tengah jalan. Exception lolos dari blok
# `with` -> psycopg menjalankan rollback sebelum menutup koneksi,
# sehingga UPDATE pertama ikut dibatalkan.
try:
    with psycopg.connect(**KONEKSI) as conn:
        conn.execute("UPDATE produk SET stok = stok - 5 WHERE id = 3")
        conn.execute(
            "INSERT INTO produk (id, nama, harga, stok)"
            " VALUES (%s, %s, %s, %s)",
            (1, "Produk Duplikat", 100000, 1),
        )
except errors.UniqueViolation:
    print("Transaksi 2 dibatalkan: INSERT duplikat, UPDATE ikut batal")

# Bukti akhir: hanya perubahan transaksi 1 yang tersimpan.
with psycopg.connect(**KONEKSI) as conn:
    cur = conn.execute(
        "SELECT id, stok FROM produk WHERE id IN (1, 2, 3) ORDER BY id"
    )
    print("Stok akhir (id, stok):", cur.fetchall())
