ACID in Database Management
ACID is an acronym that stands for Atomicity, Consistency, Isolation, and Durability. These four principles form the cornerstone of transaction management in database systems, ensuring that data operations are performed reliably and consistently.
The Four Pillars of ACID:
- Atomicity: Atomicity guarantees that a transaction is treated as a single, indivisible unit of work. Either all operations within the transaction are successfully completed, or none of them are. There is no partial execution or intermediate state.
- Consistency: Consistency ensures that the database remains in a valid state before and after the transaction. All constraints, rules, and relationships defined in the database schema are enforced, preserving data integrity and validity.
- Isolation: Isolation ensures that the execution of multiple transactions concurrently does not interfere with each other. Each transaction operates independently of others, as if it were the only transaction running, preventing data corruption and concurrency issues.
- Durability: Durability guarantees that the effects of a committed transaction persist even in the event of system failures, crashes, or power outages. Once a transaction is successfully committed, its changes are permanently stored in the database and cannot be lost.
// Example of an atomic transaction using TypeScript
async function transferFunds(senderId: number, recipientId: number, amount: number): Promise<void> {
try {
// Begin transaction
await database.beginTransaction();
// Deduct funds from sender's account
await database.updateAccountBalance(senderId, -amount);
// Add funds to recipient's account
await database.updateAccountBalance(recipientId, amount);
// Commit transaction
await database.commitTransaction();
} catch (error) {
// Rollback transaction in case of failure
await database.rollbackTransaction();
throw error;
}
}
In this example, the transferFunds function represents an atomic transaction that transfers funds from one account to another. If any operation within the transaction fails, the entire transaction is rolled back, ensuring atomicity and data consistency.
For example in Prisma:
// Import PrismaClient from '@prisma/client'
import { PrismaClient } from '@prisma/client';
// Instantiate PrismaClient
const prisma = new PrismaClient();
// Define a function to transfer funds between two accounts within a transaction
async function transferFunds(senderId: number, recipientId: number, amount: number): Promise<void> {
let transaction;
try {
// Start a transaction
transaction = await prisma.$transaction([
prisma.account.update({
where: { id: senderId },
data: { balance: { decrement: amount } }
}),
prisma.account.update({
where: { id: recipientId },
data: { balance: { increment: amount } }
})
]);
// Commit the transaction
await prisma.$transaction.commit(transaction);
console.log('Transaction successful!');
} catch (error) {
// If an error occurs, rollback the transaction
await prisma.$transaction.rollback(transaction);
console.error('Transaction failed:', error);
throw error;
}
}
// Usage example
async function main() {
try {
// Transfer $100 from account with ID 1 to account with ID 2
await transferFunds(1, 2, 100);
} catch (error) {
console.error('An error occurred:', error);
} finally {
// Disconnect PrismaClient
await prisma.$disconnect();
}
}
// Call main function
main();
https://www.prisma.io/docs/orm/prisma-client/queries/transactions
ACID principles are the bedrock of transaction management in modern database systems, providing a framework for ensuring reliability, consistency, and integrity of data operations. By adhering to ACID principles and leveraging transaction management mechanisms, developers can build robust and resilient database applications that meet the highest standards of data reliability and consistency. With the practical examples and insights provided in this article, you're equipped to harness the power of ACID in your database management endeavors.