/*Mamy dwie tabele: Konta (saldo użytkowników) oraz HistoriaOperacji (rejestr wszystkich ruchów). Twoim zadaniem jest przeprowadzenie przelewu kwoty 500 PLN od Użytkownika A do Użytkownika B. Operacja musi być atomowa – albo obie tabele zostaną zaktualizowane, albo żadna.
Napisz blok kodu, który:
1.	Rozpocznie transakcję.
2.	Odejmie 500 PLN z konta nr 1.
3.	Doda 500 PLN do konta nr 2.
4.	Doda wpis do historii dla konta nr 1 (ujemny).
5.	Doda wpis do historii dla konta nr 2 (dodatni).
6.	W przypadku jakiegokolwiek błędu – wycofa wszystkie zmiany.


*/


CREATE TABLE Konta (
    ID INT PRIMARY KEY,
    Nazwa VARCHAR(50),
    Saldo DECIMAL(18, 2)
);
CREATE TABLE HistoriaOperacji (
    ID INT IDENTITY PRIMARY KEY,
    KontoID INT,
    Kwota DECIMAL(18, 2),
    DataOperacji DATETIME DEFAULT GETDATE()
);

INSERT INTO Konta (ID, Nazwa, Saldo) VALUES (1, 'Użytkownik A', 1000.00);
INSERT INTO Konta (ID, Nazwa, Saldo) VALUES (2, 'Użytkownik B', 200.00);

SELECT * FROM KONTA;
SELECT * FROM HistoriaOperacji;


BEGIN TRY
    -- Rozpoczynamy jawną transakcję
    BEGIN TRANSACTION;

    DECLARE @KwotaPrzelewu DECIMAL(18,2) = 500.00;

    -- 1. Odjęcie środków od Użytkownika A
    UPDATE Konta 
    SET Saldo = Saldo - @KwotaPrzelewu 
    WHERE ID = 1;

    -- 2. Dodanie wpisu do historii dla Użytkownika A
    INSERT INTO HistoriaOperacji (KontoID, Kwota) 
    VALUES (1, -@KwotaPrzelewu);

    -- 3. Dodanie środków dla Użytkownika B
    UPDATE Konta 
    SET Saldo = Saldo + @KwotaPrzelewu 
    WHERE ID = 2;

    -- 4. Dodanie wpisu do historii dla Użytkownika B
    INSERT INTO HistoriaOperacji (KontoID, Kwota) 
    VALUES (2, @KwotaPrzelewu);

    -- Jeśli wszystko przebiegło pomyślnie, zatwierdzamy zmiany
    COMMIT TRANSACTION;
    PRINT 'Przelew zakończony sukcesem.';

END TRY
BEGIN CATCH
    -- W przypadku błędu sprawdzamy, czy transakcja jest otwarta
    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK TRANSACTION;
        PRINT 'Wystąpił błąd. Transakcja została wycofana.';
    END

    -- Wyświetlenie szczegółów błędu (opcjonalnie)
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_MESSAGE() AS ErrorMessage;
END CATCH;

/*PODSUMOWANIE:
•	Atomowość: Dzięki BEGIN TRANSACTION i ROLLBACK, jeśli serwer ulegnie awarii lub zabraknie środków w trakcie operacji (np. po kroku 1, ale przed krokiem 3), pieniądze nie "znikną" z systemu.
•	@@TRANCOUNT: Sprawdzenie liczby otwartych transakcji przed ROLLBACK zapobiega błędom w logice, gdyby transakcja została zamknięta wcześniej.
•	Obsługa błędów: Blok TRY...CATCH pozwala na eleganckie wycofanie zmian zamiast pozostawienia bazy w niespójnym stanie.
*/
