- https://chatgpt.com/c/22d9f577-17f2-4d43-9013-401b18ca58e0
1. ACID principle¶
- All DB has underlying solution for ACID
Atomicity¶
- start txn
- unit of work
- commit txn
Consistency¶
- pk
- fk
- constraints
ISOLATION¶
- READ_UNCOMMITTED >> READ_COMMITTED >> REPEATABLE_READ >> SERIALIZABLE
- code
@Transactional(isolation = Isolation.READ_COMMITTED) public void standardOperation() { // ... } SHOW default_transaction_isolation; -- Typically "read committed" ALTER SYSTEM SET default_transaction_isolation = 'repeatable read'; <<<
1. write lock (present default)¶
- problem :
no concurrency at all
- txn1 , txn2 --> both are writing same record same time.
- solution is
write-lock
- txn-1 took w-lock > performing write
- txn-2 waits
- txn-1 done
- txn-2 took w-lock
2. read/write lock¶
- problem :
Dirty read
(READ_UNCOMMITTED) :left_point: - txn1 --> writing same record same time.
- txn3 --> reading
- solution is
read/write lock
(READ_COMMITTED) :left_point:- txn-1 took w-lock > performing write
- txn-3 waits
- txn-1 done
- txn-2 took R-lock >> read
3. version/sanpshot¶
- problem :
no repeating read
- txn-1 took w-lock > performing write
- txn-2 waits
- txn-1 done
- txn-2 took R-lock >> Read
- txn-1 took w-lock > performing write AGAIN :left_point:
- txn-2 should read it again and get updated value.
- solution is
version/sanpshot
(REPEATABLE_READ) :left_point:- txn-2 will get latest from latest version
4. range lock¶
- problem :
phantom read
- solution - range lock (SERIALIZABLE) :left_point:
## SUMMARY ##
Isolation_Level Dirty_Reads Non-Repeatable-Reads Phantom-Reads
READ_UNCOMMITTED ✗ ✗ ✗
READ_COMMITTED ✓ ✗ ✗
REPEATABLE_READ ✓ ✓ ✗
SERIALIZABLE ✓ ✓ ✓
# postgres
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
# jdbc
Connection conn = dataSource.getConnection();
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Durability¶
- data never crashes
2. Lock¶
optimistic Locks¶
- read TS, Write TS, etc (TS=timestampe and version)
- add in entity :
@Version
private long version; ObjectOptimisticLockingFailureException
- Advantages
- Better performance than pessimistic locking
- No database locks held
- Works well for low-contention scenarios
- Suitable for web applications with short transactions
pessimistic Locks (postgresQL)¶
Row level lock¶
- mechanism
- SELECT FOR UPDATE (Row-Level Write Lock)
- SELECT FOR SHARE (Row-Level Read Lock)
- SELECT FOR NO KEY UPDATE (Weaker Write Lock)
-
SELECT FOR KEY SHARE (Weakest Lock)
-
Locking Options
- NOWAIT : Fails immediately if lock cannot be acquired
- SKIP LOCKED : Skips already locked rows
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
-- The row is now locked for updates by other transactions
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR SHARE;
-- Other transactions can read but cannot update this row
COMMIT;
BEGIN;
SELECT * FROM customers WHERE id = 1 FOR NO KEY UPDATE;
-- Locks row but allows updates on non-key columns
COMMIT;
BEGIN;
SELECT * FROM orders WHERE id = 1 FOR KEY SHARE;
-- Only prevents key changes
COMMIT;
table level lock¶
BEGIN;
LOCK TABLE accounts IN ACCESS EXCLUSIVE MODE;
-- Prevents all access to the table
COMMIT;
pg_lock (Monitor)¶
SELECT locktype, relation::regclass, mode, pid
FROM pg_locks
WHERE relation = 'accounts'::regclass;