% !TeX program = pdflatex
\documentclass[10pt,aspectratio=169]{beamer}

% Metropolis theme
\usetheme[progressbar=frametitle,numbering=fraction]{metropolis}

\usepackage{amsmath,amssymb}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{hyperref}

\usepackage{tikz}
\usepackage{etoolbox}
\usetikzlibrary{arrows.meta,positioning}
% --- put once in your preamble (optional, but nice) ---
\newcommand{\fin}[1]{\textcolor{blue}{\texttt{#1}}}
\newcommand{\eng}[1]{\textcolor{black}{\texttt{#1}}}
% ------------------------------------------------------------

% --- SQL highlighting ---
\newcommand{\sqlk}[1]{\textcolor{blue}{#1}}

\usepackage{listings}
\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.58,0,0.82}

\lstdefinestyle{sqlite}{
  language=SQL,
  morekeywords={
    TEXT,REAL,ROUND,CHAR,VARCHAR,INT,INTEGER,NUMERIC,DECIMAL,BOOLEAN,DATE,TIMESTAMP,
    PRAGMA,FOREIGN,PRIMARY,KEY,REFERENCES,DEFAULT,UNIQUE,CHECK,NOT,NULL,
    CREATE,ALTER,DROP,TABLE,VIEW,INDEX,
    GRANT,REVOKE,ROLE,WITH,OPTION,ALL,PRIVILEGES,CONNECT,EXECUTE,
    BEGIN,START,TRANSACTION,COMMIT,ROLLBACK,WORK,
    ISOLATION,LEVEL,SERIALIZABLE,REPEATABLE,READ,COMMITTED,UNCOMMITTED,
    CASCADE,RESTRICT,SET
  },
  basicstyle={\small\ttfamily},
  keywordstyle=\color{blue},
  commentstyle=\color{dkgreen},
  stringstyle=\color{mauve},
  numbers=none,
  showstringspaces=false,
  breaklines=true,
  breakatwhitespace=true,
  columns=flexible,
  tabsize=3,
  frame=single,
  rulecolor=\color{gray},
  xleftmargin=0.0em,
  framexleftmargin=0.0em,
  framexrightmargin=-1em,
  frameround=tttt,
}
\lstnewenvironment{codesql}{\lstset{style=sqlite}}{}

% Convenience
\newcommand{\partslide}[2]{%
  \begin{frame}[plain]
    \vfill
    {\Huge\textbf{#1}}\\[0.6em]
    {\Large #2}
    \vfill
  \end{frame}
}

\title{Database Programming in SQL -- Part II (continued)}
\subtitle{DDL, Access Control (DCL) \& Transactions (TxCL) \; (90 min)}
\author{Michael Emmerich}
\date{\today}

\begin{document}

\maketitle

% ------------------------------------------------------------
\begin{frame}{Roadmap (today)}
\begin{columns}[T,onlytextwidth]
\column{0.50\textwidth}
\textbf{1) DDL: schema \& integrity (30 min)}
\begin{itemize}
  \item Data types in practice
  \item Constraints: \sqlk{PRIMARY KEY}, \sqlk{FOREIGN KEY}, \sqlk{NOT NULL}, \sqlk{UNIQUE}, \sqlk{CHECK}, \sqlk{DEFAULT}
  \item \sqlk{ALTER TABLE} and schema evolution
  \item Views and indexes (what/why)
\end{itemize}

\column{0.50\textwidth}
\textbf{2) DCL \& TxCL (60 min)}
\begin{itemize}
  \item Access rights: roles, \sqlk{GRANT}, \sqlk{REVOKE}
  \item Transactions: \sqlk{BEGIN}/\sqlk{COMMIT}/\sqlk{ROLLBACK}
  \item ACID, isolation anomalies, isolation levels
  \item Locking, 2PL, deadlocks (conceptual)
\end{itemize}
\end{columns}
\end{frame}

% ------------------------------------------------------------
\begin{frame}{Connection to last lecture (2 min recap)}
\begin{itemize}
  \item Last time: querying data (\sqlk{SELECT}/\sqlk{WHERE}), joins, set operations, aggregation.
  \item Today: how we \emph{define} the structure, protect data, and keep it correct under concurrency.
\end{itemize}
\vspace{1mm}
\begin{block}{Mental model}
\medskip

\small
$\Rightarrow$\textbf{Schema (DDL)} says what data \emph{may exist}.\\ \quad\quad
$\Rightarrow$\textbf{Rights (DCL)} say who \emph{may do what}.\\ \quad\quad\quad
$\Rightarrow$\textbf{Transactions (TxCL)} say how concurrent changes stay \emph{correct}.
\end{block}
\end{frame}

% ======================= Part A: DDL =========================
\partslide{Part A}{Defining database structure (DDL) and Data Updates (DML)}

% ------------------------------------------------------------
\begin{frame}{SQL data types you will see often}
\small
SQL is strongly typed: each column has a declared type.
\vspace{1mm}
\begin{center}
\begin{tabular}{@{}lll@{}}
\toprule
\textbf{Type family} & \textbf{Examples} & \textbf{Typical use}\\
\midrule
Strings & \texttt{CHAR(n)}, \texttt{VARCHAR(n)}, \texttt{TEXT} & IDs, names, free text\\
Integers & \texttt{INT}, \texttt{INTEGER} & counts, years, quantities\\
Decimals & \texttt{NUMERIC(p,s)}, \texttt{DECIMAL(p,s)} & money, measurements\\
Booleans & \texttt{BOOLEAN} & flags, on/off states\\
Dates/times & \texttt{DATE}, \texttt{TIMESTAMP} & timestamps, events\\
\bottomrule
\end{tabular}
\end{center}
\vspace{1mm}
\footnotesize Practical note: exact type behavior depends on DBMS; always check your product's documentation.
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{DDL recap: \sqlk{CREATE TABLE} (structure + rules)}
\small
\begin{itemize}
  \item Tables define columns, data types, and constraints.
  \item Constraints are the \textbf{first line of defense} for data quality.
\end{itemize}
\vspace{1mm}

\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE TABLE CUSTOMER(
  customer_id   CHAR(4)      PRIMARY KEY,
  customer_name VARCHAR(15)  NOT NULL,
  city          VARCHAR(10),
  customer_type CHAR(1),
  district      CHAR(1)
);

CREATE TABLE INVOICE(
  invoice_id     CHAR(4)     PRIMARY KEY,
  year           INT,
  invoice_total  INT         CHECK (invoice_total >= 0),
  status         VARCHAR(2)  DEFAULT 'OK',
  customer_id    CHAR(4)     NOT NULL,
  FOREIGN KEY(customer_id) REFERENCES CUSTOMER(customer_id)
);
\end{lstlisting}
\end{frame}



% ------------------------------------------------------------
\begin{frame}[fragile]{Keys and referential integrity: \sqlk{PRIMARY KEY} + \sqlk{FOREIGN KEY}}
\small
\begin{columns}[T,onlytextwidth]
\column{0.52\textwidth}
\textbf{Composite primary key (relationship table)}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE TABLE INVOICE_LINE(
  invoice_id   CHAR(4),
  product_id   CHAR(4),
  quantity     INT CHECK (quantity > 0),
  PRIMARY KEY (invoice_id, product_id),
  FOREIGN KEY (invoice_id) REFERENCES INVOICE(invoice_id) ON DELETE CASCADE,
  FOREIGN KEY (product_id) REFERENCES PRODUCT(product_id) ON DELETE SET NULL
);
\end{lstlisting}

\column{0.48\textwidth}
\textbf{Referential actions (idea)}
\begin{itemize}
  \item \sqlk{RESTRICT}: deny update/delete in parent
  \item \sqlk{ON DELETE SET NULL}: null Foreign Key in child
  \item \sqlk{ON DELETE CASCADE}: propagate change/delete to child
  \item \sqlk{ON DELETE SET DEFAULT}: assign default value
\end{itemize}
\vspace{1mm}
\footnotesize Exact availability and defaults depend on the DBMS.
\end{columns}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Column constraints beyond keys}
\small
\begin{itemize}
  \item \sqlk{DEFAULT} sets a value if none is provided.
  \item \sqlk{NOT NULL} forbids missing values.
  \item \sqlk{UNIQUE} forbids duplicates.
  \item \sqlk{CHECK} enforces domain/business rules.
\end{itemize}

\vspace{1mm}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE TABLE CUSTOMER(
  customer_id   CHAR(4)      PRIMARY KEY,
  customer_name VARCHAR(15)  NOT NULL,
  email         VARCHAR(50)  UNIQUE,
  customer_type CHAR(1)      DEFAULT 'A',
  district      CHAR(1)      CHECK (district IN ('I','L','1','2','3'))
);
\end{lstlisting}

\vspace{1mm}
\footnotesize Rule of thumb: encode the \emph{stable} rules in constraints; keep volatile rules in application logic.
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Schema evolution: \sqlk{ALTER TABLE}}
\small
\begin{itemize}
  \item Databases evolve: new requirements, new columns, stricter rules.
  \item \sqlk{ALTER TABLE} supports adding/dropping columns and constraints (syntax differs across DBMS).
\end{itemize}
\vspace{1mm}

\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
-- Start minimal, then add constraints and columns
CREATE TABLE INVOICE_LINE(
  invoice_id CHAR(4),
  product_id CHAR(4)
);

ALTER TABLE INVOICE_LINE
  ADD COLUMN quantity INT;

-- In many DBMS (e.g., PostgreSQL) you can add constraints like this:
ALTER TABLE INVOICE_LINE
  ADD PRIMARY KEY (invoice_id, product_id);
\end{lstlisting}

\footnotesize Practical note: SQLite has limitations on ALTER TABLE compared to PostgreSQL/MySQL.
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Views and indexes: two important DB objects}
\begin{columns}[T,onlytextwidth]
\column{0.50\textwidth}
\textbf{View = stored query (no data stored)}
\begin{itemize}
  \item Simplifies common queries
  \item Helps define \textbf{fine-grained rights} (bridge to DCL)
\end{itemize}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE VIEW v_east_customers AS
SELECT customer_name, city, customer_type
FROM CUSTOMER
WHERE district = 'I';

SELECT * FROM v_east_customers;
\end{lstlisting}

\column{0.48\textwidth}
\textbf{Index = faster search structure}
\begin{itemize}
  \item Speeds up \sqlk{WHERE}/\sqlk{JOIN}/\sqlk{ORDER BY} patterns
  \item Costs extra space and slows inserts/updates
\end{itemize}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE INDEX customer_name_idx
ON CUSTOMER(customer_name);

DROP INDEX customer_name_idx;
\end{lstlisting}
\end{columns}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Views: stored queries for reuse, rights, and derived data}
\small
\textbf{View = stored query (typically no data stored)}
\begin{itemize}
  \item Simplifies common queries and hides complexity
  \item Helps define \textbf{fine-grained access rights} (expose only selected columns/rows)
  \item Can provide \textbf{derived attributes} and \textbf{unit conversions}
\end{itemize}

\vspace{1mm}
\textbf{Example (SQLite): derived attributes + unit conversion}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
-- Assume table CITIZEN(citizen_id, name, city, size_cm, birthdate)

CREATE VIEW v_citizen_profile AS
SELECT
  citizen_id,
  city,
  ROUND(size_cm / 30.48, 2) AS size_ft,  -- cm -> feet
  CAST((julianday('now') - julianday(birthdate)) / 365.25 AS INT) AS age_years
FROM CITIZEN;

SELECT * FROM v_citizen_profile;
\end{lstlisting}

\vspace{1mm}
\textbf{Privacy idea: aggregates make individual data disappear (public health style)}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE VIEW v_city_health_stats AS
SELECT
  city,
  ROUND(AVG(size_cm), 1) AS avg_size_cm,
  ROUND(AVG(size_cm / 30.48), 2) AS avg_size_ft
FROM CITIZEN
GROUP BY city;
\end{lstlisting}
\end{frame}


% ------------------------------------------------------------
\begin{frame}[fragile]{Indexes: faster search structures (with trade-offs)}
\small
\textbf{Index = auxiliary structure to speed up lookups}
\begin{itemize}
  \item Speeds up \sqlk{WHERE} / \sqlk{JOIN} / \sqlk{ORDER BY}
  \item Costs extra space and can slow \sqlk{INSERT}/\sqlk{UPDATE}/\sqlk{DELETE}
\end{itemize}

\vspace{1mm}
\textbf{Common index types (concept)}
\begin{itemize}
  \item \textbf{Sorted list by attribute values}: fast search, but updates can be expensive
  \item \textbf{B+ tree}: keeps keys sorted, supports efficient updates, and supports \textbf{range queries}
  \item \textbf{Hash index}: use a hash function to map key $\rightarrow$ bucket/page; great for equality lookups,
        but not for ranges
\end{itemize}

\vspace{-2mm}
\textbf{Example: range query (benefits from B+ tree-like indexing)}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
CREATE INDEX citizen_birthdate_idx
ON CITIZEN(birthdate);

-- Range query: citizens born between 1973 and 1993
SELECT citizen_id, birthdate
FROM CITIZEN
WHERE birthdate BETWEEN '1973-01-01' AND '1993-12-31';
\end{lstlisting}
\end{frame}


% ------------------------------------------------------------
\begin{frame}{From DDL to DML: changing the data}
\small
After \sqlk{CREATE TABLE}, we usually start manipulating rows using \textbf{DML}:
\vspace{1mm}
\begin{itemize}
  \item \sqlk{INSERT} = add new rows
  \item \sqlk{UPDATE} = modify existing rows
  \item \sqlk{DELETE} = remove rows
\end{itemize}
\vspace{1mm}
\begin{block}{CRUD mapping (common in apps)}
\medskip

\footnotesize
Create (rows) $\rightarrow$ \sqlk{INSERT}\quad
Read $\rightarrow$ \sqlk{SELECT}\quad
Update $\rightarrow$ \sqlk{UPDATE}\quad
Delete $\rightarrow$ \sqlk{DELETE}
\end{block}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{\sqlk{INSERT}: adding rows}
\small
\begin{itemize}
  \item Always prefer the \textbf{explicit column list} (robust to schema changes).
  \item Columns not mentioned become \texttt{NULL} or their \sqlk{DEFAULT}, if defined.
\end{itemize}
\vspace{1mm}

\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
-- Insert one customer
INSERT INTO CUSTOMER (customer_id, customer_name, city, customer_type, district)
VALUES ('C001', 'Anna', 'Jyvaskyla', 'A', 'I');

-- Insert an invoice (status uses DEFAULT 'OK')
INSERT INTO INVOICE (invoice_id, year, invoice_total, customer_id)
VALUES ('I001', 2025, 120, 'C001');

-- Insert multiple rows (supported in most DBMS incl. PostgreSQL, MySQL, SQLite)
INSERT INTO CUSTOMER (customer_id, customer_name, city, customer_type, district)
VALUES
  ('C002', 'Ben',  'Turku',     'A', 'L'),
  ('C003', 'Cleo', 'Helsinki',  'B', '2');
\end{lstlisting}

\vspace{0.5em}
\footnotesize
Typical failure modes: duplicate \sqlk{PRIMARY KEY}, \sqlk{FOREIGN KEY} missing parent, \sqlk{CHECK} violated.
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{\sqlk{UPDATE}: changing existing rows}
\small
\begin{itemize}
  \item \sqlk{UPDATE} changes \textbf{all rows that match} the \sqlk{WHERE} condition.
  \item \textbf{Without \sqlk{WHERE}}: you update \emph{every row} (common accident).
\end{itemize}
\vspace{1mm}

\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
-- Mark an invoice as paid
UPDATE INVOICE
SET status = 'PA'
WHERE invoice_id = 'I001';

-- Correct a total (also demonstrates an expression)
UPDATE INVOICE
SET invoice_total = invoice_total + 10
WHERE year = 2025
  AND status = 'OK';

-- Update multiple columns at once
UPDATE CUSTOMER
SET city = 'Tampere',
    district = '1'
WHERE customer_id = 'C002';
\end{lstlisting}

\vspace{0.5em}
\footnotesize Tip: do a \sqlk{SELECT ... WHERE ...} first to verify which rows will be affected.
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{\sqlk{DELETE}: removing rows}
\small
\begin{itemize}
  \item \sqlk{DELETE} removes \textbf{rows}, not table structure (that would be \sqlk{DROP TABLE}).
  \item \textbf{Without \sqlk{WHERE}}: you delete \emph{every row}.
  \item Foreign keys may block deletion (e.g., \sqlk{RESTRICT}) or propagate it (\sqlk{CASCADE}).
\end{itemize}
\vspace{1mm}

\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
-- Delete one invoice (only works if no referencing rows, or CASCADE is set)
DELETE FROM INVOICE
WHERE invoice_id = 'I001';

-- Delete all "test" customers (example condition)
DELETE FROM CUSTOMER
WHERE customer_name LIKE 'Test%';

-- Delete ALL rows (table remains!)
DELETE FROM INVOICE;
\end{lstlisting}

\vspace{0.5em}
\footnotesize In practice: deletions are often done inside transactions, and sometimes replaced by “soft delete”
(e.g., a column \texttt{is\_active}).
\end{frame}


% ======================= Part B: DCL =========================
\partslide{Part B}{Defining access rights (DCL)}

% ------------------------------------------------------------
\begin{frame}{Roles, users, and privileges (concept)}
\small
\begin{itemize}
  \item SQL standard abstracts users/groups as \textbf{roles}.
  \item Every DB object has an \textbf{owner} (typically the creator).
  \item Owners can grant/revoke privileges to other roles.
\end{itemize}
\vspace{1mm}

\begin{block}{Typical privileges}
\footnotesize
\begin{tabular}{@{}ll@{}}
\toprule
\textbf{Privilege} & \textbf{Allows}\\
\midrule
\texttt{CONNECT} & connect to database\\
\texttt{SELECT} & read data\\
\texttt{INSERT} & insert rows\\
\texttt{UPDATE} & modify rows/columns\\
\texttt{DELETE} & delete rows\\
\texttt{EXECUTE} & execute routines\\
\texttt{ALL PRIVILEGES} & all above except \texttt{CONNECT}\\
\bottomrule
\end{tabular}
\end{block}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{\sqlk{GRANT}: giving rights (with delegation option)}
\small
\begin{columns}[T,onlytextwidth]
\column{0.55\textwidth}
\textbf{General form}
\begin{codesql}
GRANT privilege[, privilege]*
ON object
TO role[, role]*
[WITH GRANT OPTION];
\end{codesql}

\textbf{Example: allow reading and updating, and allow re-granting}
\begin{codesql}
GRANT SELECT, UPDATE
ON INVOICE
TO analyst_role
WITH GRANT OPTION;
\end{codesql}

\column{0.45\textwidth}
\textbf{Column-level grants (fine-grained)}
\begin{codesql}
GRANT UPDATE (invoice_total, status)
ON INVOICE
TO billing_clerk;
\end{codesql}

\vspace{1mm}
\footnotesize Tip: combine with \textbf{views} to expose only selected columns/rows.
\end{columns}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Roles can be granted to roles (hierarchies)}
\small
\begin{itemize}
  \item Role hierarchies help manage many users: one grant updates many accounts.
  \item Creating users/roles is DBMS-specific (example shown in PostgreSQL style).
\end{itemize}

\vspace{1mm}
\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
-- PostgreSQL-like example:
CREATE ROLE masa
  WITH PASSWORD 'jkl0088'
  IN ROLE varastotyontekijat
  LOGIN
  VALID UNTIL 'May 8 11:30:00 2016';

-- Grant role to role (inherit privileges)
GRANT analyst_role TO intern_role;
\end{lstlisting}

\vspace{0.3em}
\footnotesize
\fin{varastotyontekijat}\footnote{Finnish (standard spelling): \emph{varastoty\"ontekij\"at} = “warehouse workers”.
Parts: \emph{varasto} = warehouse; \emph{ty\"ontekij\"a} = worker; \emph{-t} = plural.}
= \eng{warehouse\_workers}.

\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{\sqlk{REVOKE}: removing rights (and what happens downstream)}
\small
\begin{columns}[T,onlytextwidth]
\column{0.56\textwidth}
\textbf{General form}
\begin{codesql}
REVOKE [GRANT OPTION FOR] privilege[, privilege]*
ON object
FROM role[, role]*;
\end{codesql}

\textbf{Remove only delegation right}
\begin{codesql}
REVOKE GRANT OPTION FOR SELECT
ON INVOICE
FROM analyst_role;
\end{codesql}

\column{0.44\textwidth}
\textbf{Cascading effect (idea)}
\begin{itemize}
  \item If A granted to B \emph{with grant option}
  \item and B granted further to C,
  \item then revoking from B typically also removes the derived right from C.
\end{itemize}

\vspace{1mm}
\textbf{Best practice}
\begin{itemize}
  \item least privilege
  \item prefer views for fine-grained exposure
\end{itemize}
\end{columns}
\end{frame}

% ======================= Part C: TxCL =========================
\partslide{Part C}{Transaction control (TxCL)}

% ------------------------------------------------------------
\begin{frame}[fragile]{Transactions in SQL: the 3 core commands}
\small
\begin{itemize}
  \item A transaction groups 1..n operations into one logical unit of work.
  \item SQL transaction control uses:
\end{itemize}
\vspace{1mm}
\begin{codesql}
BEGIN [TRANSACTION];
-- ... your SELECT/INSERT/UPDATE/DELETE ...
COMMIT;   -- make changes permanent and visible
-- or
ROLLBACK; -- cancel changes of this transaction
\end{codesql}

\vspace{1mm}
\footnotesize Many systems also have \emph{autocommit} mode: each statement becomes its own transaction unless you BEGIN explicitly.
\end{frame}

% ------------------------------------------------------------
\begin{frame}{ACID: what DBMSs try to guarantee}
\small
\begin{block}{A -- Atomicity}
Either all operations succeed or none (failure triggers rollback).
\end{block}
\begin{block}{C -- Consistency}
Database moves from one consistent state to another (constraints + rules hold).
\end{block}
\begin{block}{I -- Isolation}
Concurrent transactions behave as if executed in some serial order.
\end{block}
\begin{block}{D -- Durability}
After commit, results persist even after crashes (within practical limits).
\end{block}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Example (concept): guard a business rule with rollback}
\small
Business rule: bank account balance must not go below 0.
\vspace{1mm}

\begin{lstlisting}[style=sqlite,basicstyle=\scriptsize\ttfamily]
BEGIN TRANSACTION;
SELECT saldo
FROM tili
WHERE tilinro = :account_no;

-- if account not found: ROLLBACK;

UPDATE tili
SET saldo = saldo - :amount
WHERE tilinro = :account_no;

SELECT saldo
FROM tili
WHERE tilinro = :account_no;

-- if saldo < 0: ROLLBACK;

COMMIT;
\end{lstlisting}

\vspace{0.3em}
\footnotesize
\fin{tili}\footnote{Finnish: \emph{tili} = account (e.g., bank account, user account).}
= \eng{account},\;
\fin{tilinro}\footnote{Common abbreviation: \emph{tilinro} < \emph{tilinumero} = account number.
(\emph{numero} = number; \emph{nro} is a widely used Finnish abbreviation for “number”.)}
= \eng{account\_no},\;
\fin{saldo}\footnote{Finnish: \emph{saldo} = balance (current amount in an account).}
= \eng{balance}.

\footnotesize (Pseudo-code style: checks are done in the host program or via triggers.)
\end{frame}

% ------------------------------------------------------------
\begin{frame}{Isolation: what can go wrong with concurrency?}
\small
If transactions run in parallel, anomalies may violate the “as-if-serial” idea.

\vspace{1mm}
\begin{block}{Classic anomalies}
\begin{itemize}
  \item \textbf{Lost update}: two writers overwrite each other (final state misses one update).
  \item \textbf{Dirty read}: a transaction reads uncommitted changes from another transaction.
  \item \textbf{Non-repeatable read}: re-reading a row yields a different value (someone committed an update).
  \item \textbf{Phantom read}: re-running a range query yields different \emph{set of rows} (someone inserted/deleted in the range).
\end{itemize}
\end{block}
\end{frame}

% ------------------------------------------------------------
\begin{frame}[fragile]{Lost update (simple example)}
\small
Two transactions both add 20 to the same balance, but one update is lost.
\vspace{1mm}

\begin{center}
\begin{tabular}{@{}p{0.10\textwidth}p{0.43\textwidth}p{0.43\textwidth}@{}}
\toprule
\textbf{Time} & \textbf{T1} & \textbf{T2}\\
\midrule
$t_1$ & Read balance = 100  & --- \\
$t_2$ & ---                & Read balance = 100 \\
$t_3$ & Write balance = 120 & --- \\
$t_4$ & ---                & Write balance = 120 \\
\bottomrule
\end{tabular}
\end{center}

\vspace{1mm}
\begin{block}{Observation}
\small
Parallel result: 120.\quad Serial result First T1 then T2: 140.\quad
Isolation aims to prevent this mismatch.
\end{block}
\end{frame}

% ------------------------------------------------------------
\begin{frame}{Isolation levels (SQL standard idea)}
\small
Looser isolation can be faster but allows more anomalies.

\vspace{1mm}
\begin{center}
\begin{tabular}{@{}lccc@{}}
\toprule
\textbf{Isolation level} & \textbf{Dirty reads} & \textbf{Non-repeatable} & \textbf{Phantoms}\\
\midrule
\texttt{SERIALIZABLE} & no & no & no\\
\texttt{REPEATABLE READ} & no & no & yes\\
\texttt{READ COMMITTED} & no & yes & yes\\
\texttt{READ UNCOMMITTED} & yes & yes & yes\\
\bottomrule
\end{tabular}
\end{center}

\vspace{1mm}
\footnotesize Exact behavior can differ by DBMS; the table captures the \emph{standard} intent.
\end{frame}

% ------------------------------------------------------------
\begin{frame}{Concurrency control: how isolation is implemented (concept)}
\small
\begin{itemize}
  \item A \textbf{schedule} is the interleaving of operations of concurrent transactions.
  \item A schedule is \textbf{serializable} if it is equivalent to some serial order.
  \item DBMSs use techniques such as:
  \begin{itemize}
    \item \textbf{Locking} (common in classic RDBMS)
    \item \textbf{Timestamp ordering} (also common in some settings)
    \item \textbf{Optimistic vs pessimistic} strategies (high-level view)
  \end{itemize}
\end{itemize}
\end{frame}



% ------------------------------------------------------------
\begin{frame}{Two-phase locking (2PL): the key protocol}
\small
2PL structures each transaction into two phases:
\vspace{1mm}
\begin{block}{Expanding phase}
Acquire all needed locks (and promotions). Do \emph{not} release locks yet.
\end{block}
\begin{block}{Shrinking phase}
Release locks when they are no longer needed. Do \emph{not} acquire new locks.
\end{block}

\vspace{1mm}
\begin{itemize}
  \item 2PL + proper lock types aims for serializability.
  \item Stronger variants:
  \begin{itemize}
    \item \textbf{Conservative 2PL}: acquire all locks before doing anything. $\Rightarrow$ Avoids deadlocks
    \item \textbf{\underline{Strict 2PL}}: keep all write locks until commit/rollback.
    $\Rightarrow$ Avoids cascading rollback.
    \item \textbf{Strong strict 2PL}: keep all locks until commit/rollback.
  \end{itemize}
\end{itemize}



Papadimitriou, C. H. (1979). The serializability of concurrent database updates. Journal of the ACM (JACM), 26(4), 631-653.

\end{frame}

% ------------------------------------------------------------
\begin{frame}{Strict 2PL example: lock upgrade causes waiting}
\small
\textbf{Notation:} \texttt{S(X)} = shared (read) lock on item X,\;
\texttt{X(X)} = exclusive (write) lock,\;
\texttt{R(X), W(X)} = read/write.\;
\textbf{Strict 2PL:} locks are released only at \sqlk{COMMIT}/\sqlk{ROLLBACK}.

\vspace{1mm}
\begin{center}
\scriptsize
\begin{tabular}{@{}r l l p{0.36\textwidth}@{}}
\toprule
\textbf{Step} & \textbf{T1} & \textbf{T2} & \textbf{Lock state / comment}\\
\midrule
1  & \texttt{S(A)} &  & \texttt{S(A)} held by T1\\
2  & \texttt{R(A)} &  & read ok\\
3  & \texttt{X(A)} &  & upgrade ok (no other holders)\\
4  & \texttt{W(A)} &  & \texttt{X(A)} held by T1\\
5  &  & \texttt{S(B)} & \texttt{S(B)} held by T2\\
6  &  & \texttt{R(B)} & read ok\\
7  & \texttt{S(B)} &  & compatible: T1 also gets \texttt{S(B)}\\
8  & \texttt{R(B)} &  & read ok\\
9  & \texttt{X(B)} &  & \textbf{WAIT}: cannot upgrade while T2 holds \texttt{S(B)}\\
10 &  & \sqlk{COMMIT} & strict 2PL: T2 releases \texttt{S(B)} only now\\
11 & \texttt{X(B)} &  & upgrade granted\\
12 & \texttt{W(B)} &  & write ok\\
13 & \sqlk{COMMIT} &  & strict 2PL: T1 releases \texttt{X(A)}, \texttt{X(B)}\\
\bottomrule
\end{tabular}
\end{center}

\footnotesize
Takeaway: even a \emph{reader} (T2) can block a \emph{writer} (T1) under strict 2PL when the writer needs an \texttt{S$\rightarrow$X} upgrade.
\end{frame}




% ------------------------------------------------------------
\begin{frame}{Deadlocks: circular waiting for locks}
\small
\begin{itemize}
  \item Two-phase locking (2PL) helps isolation/serializability, but it can create \textbf{deadlocks}.
  \item A \textbf{deadlock} is a \textbf{cycle of waiting}: each transaction waits for a lock held by another.
  \item The situation does \emph{not} resolve by itself: the DBMS must abort (rollback) one transaction.
\end{itemize}

\vspace{1mm}
\begin{center}
\begin{tabular}{@{}l p{0.40\textwidth} p{0.40\textwidth}@{}}
\toprule
\textbf{Step} & \textbf{T1} & \textbf{T2}\\
\midrule
1 & X-lock(A) granted & \\
2 &  & X-lock(B) granted\\
3 & request X-lock(B) \emph{(blocked)} & \\
4 &  & request X-lock(A) \emph{(blocked)}\\
\midrule
 & \multicolumn{2}{l}{Now: T1 waits for B (held by T2) and T2 waits for A (held by T1) $\Rightarrow$ deadlock.}\\
\bottomrule
\end{tabular}
\end{center}

\footnotesize
Key idea: the \emph{wait-for} relation forms a cycle (T1 waits for T2, and T2 waits for T1).
\end{frame}


% In preamble:
% \usepackage{tikz}
% \usetikzlibrary{arrows.meta,positioning}

% ------------------------------------------------------------

\newcommand{\stickman}[2]{%
  % #1 x, #2 y
  \draw[line width=0.9pt] (#1,#2) circle (0.25);            % head
  \draw[line width=0.9pt] (#1,#2-0.25) -- (#1,#2-1.0);      % body
  \draw[line width=0.9pt] (#1,#2-0.45) -- (#1-0.45,#2-0.75);% left arm
  \draw[line width=0.9pt] (#1,#2-0.45) -- (#1+0.45,#2-0.75);% right arm
  \draw[line width=0.9pt] (#1,#2-1.0) -- (#1-0.4,#2-1.45);  % left leg
  \draw[line width=0.9pt] (#1,#2-1.0) -- (#1+0.4,#2-1.45);  % right leg
}
\begin{frame}{Deadlock (human edition)}
\centering
\begin{tikzpicture}[scale=1, every node/.style={font=\small}]
  % Corridor
  \draw[rounded corners=6pt, line width=1pt] (-6,-1.6) rectangle (6,1.6);
  \node[font=\footnotesize] at (0,1.9) {A very narrow corridor (capacity = 1)};

  % Center "blocked" zone
  \draw[dashed] (0,-1.6) -- (0,1.6);
  \node[font=\footnotesize] at (0,-2.0) {critical section};

  % Two simple men
  \stickman{-0.8}{0}
  \stickman{ 0.8}{0}
  \node at (-3.8,-1.1) {\footnotesize T1};
  \node at ( 3.8,-1.1) {\footnotesize T2};

  % Intent arrows
  \draw[-{Stealth[length=3mm]}, line width=1pt] (-3.1,0.9) -- (-0.6,0.9);
  \draw[-{Stealth[length=3mm]}, line width=1pt] ( 3.1,0.9) -- ( 0.6,0.9);

  % Speech bubbles (simple)
  \node[align=center] at (-1.75,0.875) {“After you.”\\ \footnotesize (holds the door-lock)};
  \node[align=center] at (1.75,0.875) {“No, after you!”\\ \footnotesize (also holds a lock)};

  % Deadlock label
  \node[font=\bfseries] at (0,-2.95) {DEADLOCK};
  \node[font=\footnotesize, align=center] at (0,-4.25)
    {Both are polite. Neither moves.\\
     The DBMS solution: “Sorry—one of you has to \texttt{ROLLBACK}.”};
\end{tikzpicture}
\end{frame}



% ------------------------------------------------------------
\begin{frame}{Deadlocks: typical handling strategies}
\small
\begin{columns}[T,onlytextwidth]
\column{0.5\textwidth}
\textbf{1) Prevention (avoid cycles)}
\begin{itemize}
  \item \textbf{Lock ordering}: always request locks in a fixed global order\\
        (e.g., by primary key, table order, or object id).
  \item \textbf{Timestamp priority protocols}:
  \begin{itemize}
    \item \textbf{wait-die}: \emph{older may wait}; \emph{younger aborts} if it would wait for older.
    \item \textbf{wound-wait}: \emph{older aborts (wounds) younger}; \emph{younger may wait} for older.
  \end{itemize}
\end{itemize}

\column{0.48\textwidth}
\textbf{2) Detection (allow, then resolve)}
\begin{itemize}
  \item DBMS maintains a \textbf{wait-for graph}.
  \item If there is a \textbf{cycle}, a deadlock is detected.
  \item DBMS chooses a \textbf{victim}, does \sqlk{ROLLBACK}, releases locks.
\end{itemize}

\vspace{1mm}
\textbf{3) Timeout (simple fallback)}
\begin{itemize}
  \item If a lock wait exceeds a threshold: abort + retry.
\end{itemize}
\end{columns}

\vspace{1mm}
\footnotesize
Practical takeaway: deadlocks are normal in concurrent systems; robust applications handle “transaction aborted” by retrying.
\end{frame}



% ------------------------------------------------------------
\begin{frame}[fragile]{In SQL: setting isolation level (typical pattern)}
\small
Syntax varies by DBMS, but the idea is:

\vspace{1mm}
\begin{codesql}
BEGIN;
-- (DBMS-specific) set isolation for this transaction:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- do work safely
SELECT ...;
UPDATE ...;

COMMIT;
\end{codesql}

\vspace{1mm}
\footnotesize Takeaway: you choose an isolation level to trade off speed vs anomalies.
\end{frame}

% ------------------------------------------------------------
% \begin{frame}{Mini-exercises for class (10 min)}
% \small
% \begin{enumerate}
%   \item Add a constraint: In \texttt{INVOICE}, enforce \texttt{invoice\_total >= 0} and status in \{\texttt{'OK'},\texttt{'PA'}\}.
%   \item Create a view \texttt{v\_customer\_public(customer\_id, city)} and explain why it is useful for access rights.
%   \item Explain which isolation level you would pick for:
%     \begin{itemize}
%       \item (a) a live dashboard that may tolerate slightly stale reads
%       \item (b) transferring money between accounts
%     \end{itemize}
% \end{enumerate}
% \end{frame}

% ------------------------------------------------------------
\begin{frame}{Summary}
\small
\begin{itemize}
  \item \textbf{DDL}: define structure + constraints; evolve schema via \sqlk{ALTER}; use \textbf{views} and \textbf{indexes}.
  \item \textbf{DCL}: manage access via roles and \sqlk{GRANT}/\sqlk{REVOKE}; prefer least privilege and views for fine-grained rights.
  \item \textbf{TxCL}: group operations into transactions; ACID; isolation levels; locking/2PL; deadlocks exist and are handled by the DBMS.
\end{itemize}
\end{frame}

\begin{frame}[plain]
\vfill
\centering
{\Large \textbf{Next up in the course}}\\[0.8em]
\begin{itemize}
  \item More query and data definition patterns and performance intuitions
  \item Interfacing a SQL database management system with a host programming language
  \item Practical exercises on your DBMS
\end{itemize}
\vfill
\end{frame}

\end{document}
