🔹 What are Transactions in DBMS?
A transaction in DBMS is a sequence of one or more SQL operations (like INSERT, UPDATE, DELETE, SELECT) that are executed as a single unit of work.
A transaction is either fully completed (committed) or completely rolled back (undone) — never left halfway.
🔹 Key Properties: ACID
Every transaction must satisfy the ACID properties:
Property | Meaning |
|---|---|
A – Atomicity | All operations in a transaction are done or none. No partial updates. |
C – Consistency | The database moves from one valid state to another valid state. |
I – Isolation | Transactions don’t interfere with each other when running simultaneously. |
D – Durability | Once a transaction is committed, its changes are permanent — even in case of crash. |
🔹 Example Banking System:
Transferring ₹100 from Account A to Account B:
-- Start Transaction
BEGIN;
-- Step 1: Deduct from A
UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A';
-- Step 2: Add to B
UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B';
-- Commit the changes
COMMIT;If anything fails in between (e.g. second update), you can do:
ROLLBACK;This undoes all changes made so far in the transaction.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transactions & ACID — Try It Yourself</title>
<style>
.infographic-transaction {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #16a34a;
--good-soft: #dcfce7;
--bad: #dc2626;
--bad-soft: #fee2e2;
--display-font: Georgia, 'Iowan Old Style', serif;
--body-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--mono-font: 'SF Mono', Consolas, monospace;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 940px;
margin: 0 auto;
box-sizing: border-box;
overflow-x: hidden;
}
.infographic-transaction[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4ade80;
--good-soft: #123420;
--bad: #f87171;
--bad-soft: #3a1414;
}
.infographic-transaction * { box-sizing: border-box; }
.tx-head { text-align: center; margin-bottom: 0.25rem; }
.tx-head h2 {
font-family: var(--display-font);
font-size: 1.95rem;
margin: 0 0 0.5rem;
}
.tx-head p {
color: var(--ink-soft);
font-size: 1rem;
margin: 0 auto;
max-width: 600px;
line-height: 1.55;
}
.tx-states {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
gap: 0.4rem;
margin: 1.75rem 0 0;
}
.tx-state-pill {
font-size: 0.78rem;
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.4rem 0.85rem;
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.2s;
}
.tx-state-pill.is-current { background: var(--accent); color: #fff; border-color: var(--accent); transform: scale(1.08); }
.tx-state-pill.is-bad-current { background: var(--bad); color: #fff; border-color: var(--bad); transform: scale(1.08); }
.tx-state-arrow { color: var(--line); font-size: 0.9rem; }
.tx-accounts { display: flex; gap: 1.25rem; justify-content: center; margin-top: 1.75rem; flex-wrap: wrap; }
.tx-account {
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 10px;
padding: 1rem 1.5rem;
text-align: center;
min-width: 140px;
transition: border-color 0.2s;
}
.tx-account.is-touched { border-color: var(--accent); }
.tx-account-label { font-size: 0.78rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.04em; }
.tx-account-balance { font-family: var(--mono-font); font-size: 1.5rem; margin-top: 0.3rem; transition: color 0.2s; }
.tx-account-balance.is-flash { color: var(--accent); }
.tx-frame {
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 10px;
padding: 1.25rem;
margin-top: 1.75rem;
}
.tx-btn-row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.tx-btn {
font: inherit;
font-size: 0.85rem;
background: var(--accent);
color: #fff;
border: none;
border-radius: 7px;
padding: 0.6rem 1.1rem;
cursor: pointer;
}
.tx-btn:hover { opacity: 0.9; }
.tx-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.tx-btn.is-danger { background: var(--bad); }
.tx-btn.is-secondary { background: var(--paper); color: var(--ink); border: 1px solid var(--line); }
.tx-log {
margin-top: 1.1rem;
background: var(--ink);
color: #d4e2ff;
border-radius: 8px;
padding: 0.85rem 1rem;
font-family: var(--mono-font);
font-size: 0.8rem;
line-height: 1.7;
min-height: 3rem;
}
.infographic-transaction[data-theme="dark"] .tx-log { background: #05070a; }
.tx-log .tx-log-line { opacity: 0; animation: tx-line-in 0.3s ease forwards; }
@keyframes tx-line-in { to { opacity: 1; } }
.tx-log .tx-log-comment { color: #7c8aa8; }
.tx-log .tx-log-commit { color: #4ade80; }
.tx-log .tx-log-rollback { color: #f87171; }
.tx-log-placeholder { color: #7c8aa8; font-style: italic; }
.tx-msg {
margin-top: 1rem;
padding: 0.7rem 0.9rem;
border-radius: 8px;
font-size: 0.85rem;
line-height: 1.55;
display: none;
}
.tx-msg.is-visible { display: block; }
.tx-msg.msg-bad { background: var(--bad-soft); color: var(--bad); }
.tx-msg.msg-good { background: var(--good-soft); color: var(--good); }
.tx-acid-progress {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
justify-content: center;
margin-top: 1.75rem;
}
.tx-acid-chip {
font-size: 0.78rem;
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.45rem 0.9rem;
color: var(--ink-soft);
transition: background 0.25s, color 0.25s, border-color 0.25s, transform 0.25s;
}
.tx-acid-chip.is-done {
background: var(--good-soft);
color: var(--good);
border-color: var(--good);
transform: scale(1.06);
}
@media (prefers-reduced-motion: reduce) {
.infographic-transaction *, .infographic-transaction *::before, .infographic-transaction *::after {
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
}
}
</style>
</head>
<body>
<div class="infographic-transaction" id="transaction">
<div class="tx-head">
<h2>Transactions & ACID — Try It Yourself</h2>
<p>Transfer ₹100 from Account A to Account B, step by step — or interrupt it partway and watch ROLLBACK undo everything.</p>
</div>
<div class="tx-states" id="txStates">
<span class="tx-state-pill" data-state="active">Active</span>
<span class="tx-state-arrow">→</span>
<span class="tx-state-pill" data-state="partial">Partially Committed</span>
<span class="tx-state-arrow">→</span>
<span class="tx-state-pill" data-state="committed">Committed</span>
<span class="tx-state-arrow">/</span>
<span class="tx-state-pill" data-state="failed">Failed</span>
<span class="tx-state-arrow">→</span>
<span class="tx-state-pill" data-state="aborted">Aborted</span>
</div>
<div class="tx-accounts">
<div class="tx-account" id="txAccA">
<div class="tx-account-label">Account A</div>
<div class="tx-account-balance" id="txBalA">₹500</div>
</div>
<div class="tx-account" id="txAccB">
<div class="tx-account-label">Account B</div>
<div class="tx-account-balance" id="txBalB">₹300</div>
</div>
</div>
<div class="tx-frame">
<div class="tx-btn-row">
<button class="tx-btn" id="txBegin" type="button">BEGIN</button>
<button class="tx-btn" id="txDeduct" type="button" disabled>Deduct ₹100 from A</button>
<button class="tx-btn" id="txAdd" type="button" disabled>Add ₹100 to B</button>
<button class="tx-btn" id="txCommit" type="button" disabled>COMMIT</button>
<button class="tx-btn is-danger" id="txFail" type="button" disabled>💥 Simulate failure → ROLLBACK</button>
<button class="tx-btn is-secondary" id="txReset" type="button">Reset</button>
</div>
<div class="tx-log" id="txLog"><span class="tx-log-placeholder">Click BEGIN to start the transaction...</span></div>
<div class="tx-msg" id="txMsg"></div>
</div>
<div class="tx-acid-progress" id="txAcidProgress">
<span class="tx-acid-chip" data-letter="A">A · Atomicity</span>
<span class="tx-acid-chip" data-letter="C">C · Consistency</span>
<span class="tx-acid-chip" data-letter="I">I · Isolation</span>
<span class="tx-acid-chip" data-letter="D">D · Durability</span>
</div>
</div>
<script>
(function () {
const wrapper = document.getElementById('transaction');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
(function () {
let baseA = 500, baseB = 300;
let balA = baseA, balB = baseB;
let step = 'idle'; // idle -> active -> deducted -> partial -> committed | aborted
const balAEl = document.getElementById('txBalA');
const balBEl = document.getElementById('txBalB');
const accAEl = document.getElementById('txAccA');
const accBEl = document.getElementById('txAccB');
const log = document.getElementById('txLog');
const msg = document.getElementById('txMsg');
const statePills = document.querySelectorAll('.tx-state-pill');
const btnBegin = document.getElementById('txBegin');
const btnDeduct = document.getElementById('txDeduct');
const btnAdd = document.getElementById('txAdd');
const btnCommit = document.getElementById('txCommit');
const btnFail = document.getElementById('txFail');
const btnReset = document.getElementById('txReset');
function renderBalances() {
balAEl.textContent = '₹' + balA;
balBEl.textContent = '₹' + balB;
}
function flash(el) {
el.classList.add('is-flash');
setTimeout(() => el.classList.remove('is-flash'), 500);
}
function setState(name, bad) {
statePills.forEach(p => {
p.classList.remove('is-current', 'is-bad-current');
if (p.dataset.state === name) p.classList.add(bad ? 'is-bad-current' : 'is-current');
});
}
function appendLog(text, cls) {
if (log.querySelector('.tx-log-placeholder')) log.innerHTML = '';
const line = document.createElement('div');
line.className = 'tx-log-line' + (cls ? ' ' + cls : '');
line.textContent = text;
log.appendChild(line);
}
function showMsg(text, type) {
msg.textContent = text;
msg.className = 'tx-msg is-visible msg-' + type;
}
function markAcid(letters) {
letters.forEach(l => {
const chip = document.querySelector('.tx-acid-chip[data-letter="' + l + '"]');
if (chip) chip.classList.add('is-done');
});
}
function setButtons() {
btnBegin.disabled = step !== 'idle';
btnDeduct.disabled = step !== 'active';
btnAdd.disabled = step !== 'deducted';
btnCommit.disabled = step !== 'partial';
btnFail.disabled = !(step === 'active' || step === 'deducted' || step === 'partial');
}
btnBegin.addEventListener('click', () => {
step = 'active';
appendLog('BEGIN;', 'tx-log-comment');
setState('active');
setButtons();
msg.className = 'tx-msg';
});
btnDeduct.addEventListener('click', () => {
balA -= 100;
renderBalances();
flash(balAEl);
accAEl.classList.add('is-touched');
appendLog("UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A';");
step = 'deducted';
setButtons();
});
btnAdd.addEventListener('click', () => {
balB += 100;
renderBalances();
flash(balBEl);
accBEl.classList.add('is-touched');
appendLog("UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B';");
step = 'partial';
setState('partial');
setButtons();
markAcid(['C', 'I']);
showMsg('👀 Both writes are done but not committed — anyone else querying A or B right now still sees the old balances, not this half-finished state. That\u2019s Isolation. And notice A + B still totals ₹800, same as before — the database is moving toward a new valid state, not a broken one. That\u2019s Consistency.', 'good');
});
btnCommit.addEventListener('click', () => {
appendLog('COMMIT;', 'tx-log-commit');
step = 'committed';
baseA = balA;
baseB = balB;
setState('committed');
setButtons();
accAEl.classList.remove('is-touched');
accBEl.classList.remove('is-touched');
showMsg('✔️ Committed — Durability kicks in now. Even if the system crashed the instant after this, A=₹' + balA + ' and B=₹' + balB + ' would still hold on restart.', 'good');
markAcid(['D']);
});
btnFail.addEventListener('click', () => {
appendLog('-- something failed mid-transaction', 'tx-log-comment');
setState('failed', true);
setTimeout(() => {
appendLog('ROLLBACK;', 'tx-log-rollback');
balA = baseA;
balB = baseB;
renderBalances();
accAEl.classList.remove('is-touched');
accBEl.classList.remove('is-touched');
step = 'aborted';
setState('aborted', true);
setButtons();
showMsg('❌ Rolled back — Atomicity in action. Even though A was already deducted, the whole transaction undoes together. Balances are exactly what they were before BEGIN.', 'bad');
markAcid(['A']);
}, 500);
});
btnReset.addEventListener('click', () => {
balA = baseA;
balB = baseB;
renderBalances();
step = 'idle';
log.innerHTML = '<span class="tx-log-placeholder">Click BEGIN to start the transaction...</span>';
msg.className = 'tx-msg';
statePills.forEach(p => p.classList.remove('is-current', 'is-bad-current'));
accAEl.classList.remove('is-touched');
accBEl.classList.remove('is-touched');
document.querySelectorAll('.tx-acid-chip').forEach(c => c.classList.remove('is-done'));
setButtons();
});
renderBalances();
setButtons();
})();
</script>
</body>
</html>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});🔹 Transaction States:
State | Description |
|---|---|
Active | The transaction has started and is performing operations. |
Partially Committed | All operations are done, waiting for commit. |
Committed | All changes are saved permanently. |
Failed | Some issue occurred (like power failure or error). |
Aborted | Changes are undone; the transaction is rolled back. |
🔹 SQL Keywords Involved:
BEGIN/START TRANSACTIONCOMMIT– Save changesROLLBACK– Undo changesSAVEPOINT– Create rollback checkpointsSET TRANSACTION– Set isolation level
✅ Summary:
A transaction is a logical unit of work that must either be fully completed or fully undone, ensuring data integrity, consistency, and reliability.