تراکنش در دنیا پایگاه داده ها: قهرمانهای گمنامِ پشت صحنه 💪
در دنیای پایگاه داده، تراکنش (Transaction) مثل یه گروه سربازه که یا با هم تا تهِ خط میرن، یا همه با هم برمیگردن. وقتی حرف از تراکنش ها میشه، خیلیها یاد تراکنش حسابهای بانکی میفتن و با خودشون میگن: «وا، من که به این پیچیدگیها نیاز ندارم!» اما حقیقت اینه که تراکنش ها فقط مال پایگاههای دادهی بانکها نیستن. خیلی وقتها مردم گیر یه سری مثالهای بانکی میافتن و فراموش میکنن که تو دنیای واقعی، تراکنش ها چقدر کاربرد دارن.
با استفاده از تراکنشها برنامهنویسها نه تنها وقتِ خودشون رو ذخیره میکنن، بلکه کد مورد نیازشون برای برنامههایی که به پایگاه داده وابسته هستن رو هم کم میکنن. اگه پایگاه داده خودش وضعیت تراکنش رو مدیریت نمیکرد، باید خود برنامهنویس این کار رو انجام میداد. به نظر ساده میاد، ولی وقتی با دادههای مرتبط به هم سروکار داشته باشیم، خیلی زود پیچیده میشه.
مثلاً به مراحل ثبتنام سادهی یه کاربر فکر کنین. این مراحل باید یه رکورد کاربر و یه رکورد حساب بسازن و بعد اونها رو به هم وصل کنن. بدون تراکنش باید تک تک مراحل رو تو برنامه بنویسیم:
کاربر رو بساز
اگه موفق نبود، خارج شو و پیام خطا بفرست
حساب رو بساز
اگه موفق نبود، کاربر رو حذف کن، خارج شو و پیام خطا بفرست
کاربر رو به حساب وصل کن
اگه موفق نبود، کاربر، حساب رو حذف کن، خارج شو و پیام خطا بفرست
اما با تراکنش، میتونیم راحتتر و تمیزتر عمل کنیم:
تراکنش رو شروع کن
حساب رو بساز
کاربر رو بساز
کاربر رو به حساب وصل کن
تراکنش موفقیتآمیز بود؟
اگه آره، پیام موفقیت رو برگردون
اگه نه، پیام خطا رو برگردون
حالا دیگه نگران این نیستیم که بخاطر یه دستوری که موفق نشده، بقیه رو پاک کنیم. یا همه با هم درست انجام میشن، یا همه با هم شکست میخورن. به همین سادگی!
خب، حالا میبینیم که تراکنش ها نه تنها پیچیده نیستن، بلکه تو خیلی از کارها میتونن دست چپ و راست برنامهنویسها باشن. دیگه این قهرمانهای گمنام دنیای پایگاه داده رو دستکم نگیرین!
#postgresql
@Code_Crafters
در دنیای پایگاه داده، تراکنش (Transaction) مثل یه گروه سربازه که یا با هم تا تهِ خط میرن، یا همه با هم برمیگردن. وقتی حرف از تراکنش ها میشه، خیلیها یاد تراکنش حسابهای بانکی میفتن و با خودشون میگن: «وا، من که به این پیچیدگیها نیاز ندارم!» اما حقیقت اینه که تراکنش ها فقط مال پایگاههای دادهی بانکها نیستن. خیلی وقتها مردم گیر یه سری مثالهای بانکی میافتن و فراموش میکنن که تو دنیای واقعی، تراکنش ها چقدر کاربرد دارن.
با استفاده از تراکنشها برنامهنویسها نه تنها وقتِ خودشون رو ذخیره میکنن، بلکه کد مورد نیازشون برای برنامههایی که به پایگاه داده وابسته هستن رو هم کم میکنن. اگه پایگاه داده خودش وضعیت تراکنش رو مدیریت نمیکرد، باید خود برنامهنویس این کار رو انجام میداد. به نظر ساده میاد، ولی وقتی با دادههای مرتبط به هم سروکار داشته باشیم، خیلی زود پیچیده میشه.
مثلاً به مراحل ثبتنام سادهی یه کاربر فکر کنین. این مراحل باید یه رکورد کاربر و یه رکورد حساب بسازن و بعد اونها رو به هم وصل کنن. بدون تراکنش باید تک تک مراحل رو تو برنامه بنویسیم:
کاربر رو بساز
اگه موفق نبود، خارج شو و پیام خطا بفرست
حساب رو بساز
اگه موفق نبود، کاربر رو حذف کن، خارج شو و پیام خطا بفرست
کاربر رو به حساب وصل کن
اگه موفق نبود، کاربر، حساب رو حذف کن، خارج شو و پیام خطا بفرست
اما با تراکنش، میتونیم راحتتر و تمیزتر عمل کنیم:
تراکنش رو شروع کن
حساب رو بساز
کاربر رو بساز
کاربر رو به حساب وصل کن
تراکنش موفقیتآمیز بود؟
اگه آره، پیام موفقیت رو برگردون
اگه نه، پیام خطا رو برگردون
حالا دیگه نگران این نیستیم که بخاطر یه دستوری که موفق نشده، بقیه رو پاک کنیم. یا همه با هم درست انجام میشن، یا همه با هم شکست میخورن. به همین سادگی!
خب، حالا میبینیم که تراکنش ها نه تنها پیچیده نیستن، بلکه تو خیلی از کارها میتونن دست چپ و راست برنامهنویسها باشن. دیگه این قهرمانهای گمنام دنیای پایگاه داده رو دستکم نگیرین!
#postgresql
@Code_Crafters
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1👏1
تراکنش های ابتدایی
سادهترین تراکنش در زیر آمده است. با استفاده از BEGIN تراکنش را شروع کرده و با COMMIT آن را پایان میدهد.
ببین، تراکنشها گروهی از عملیاتهای پایگاه داده هستن که با هم انجام میشن. گاهی اوقات، لازمه که یک مقدار شناسه یکتا برای هر رکوردی که وارد پایگاه داده میکنیم، داشته باشیم. برای این کار، از دنبالهها (sequences) استفاده میکنیم. دنبالهها، مقدار شناسه بعدی رو به صورت خودکار تولید میکنن.
حالا، فرض کن که دو تراکنش همزمان دارن داده وارد پایگاه داده میکنن. اگه هر دو تراکنش از دنبالهای استفاده کنن که هنوز نهایی نشده، ممکنه هر دو تراکنش مقدار شناسه یکسانی رو دریافت کنن. این باعث میشه که دو رکورد با یک شناسه یکسان در پایگاه داده وجود داشته باشن. این کار درست نیست و میتونه باعث مشکلاتی بشه.
برای جلوگیری از این مشکل، دنبالهها حتی قبل از اینکه تراکنش نهایی بشه، مقدار شناسه بعدی رو تولید میکنن. این کار باعث میشه که هر دو تراکنش مقدار شناسه متفاوتی رو دریافت کنن.
حالا، اگه تراکنش رو نهایی نکنی، مقدار شناسهای که بهت برمیگردونه، فقط یک مقدار موقتی هست. این مقدار تا زمانی که تراکنش نهایی بشه، در پایگاه داده ذخیره نمیشه.
اگه تراکنش رو با دستور ROLLBACK لغو کنی، مقدار شناسهای که بهت برمیگردونده، از بین میره.
برای اینکه مطمئن بشی که مقدار شناسهای که دریافت میکنی، در پایگاه داده ذخیره شده، باید تراکنش رو با دستور COMMIT نهایی کنی.
اگه در حین انجام تراکنش، خطا رخ بده، نمیتونی اون رو نهایی کنی. در این صورت، مقدار شناسهای که دریافت میکنی، در پایگاه داده ذخیره نمیشه.
#postgresql
@Code_Crafters
سادهترین تراکنش در زیر آمده است. با استفاده از BEGIN تراکنش را شروع کرده و با COMMIT آن را پایان میدهد.
sqlمثل آب خوردن کار کرد، درسته؟ شبیه اینه که یه دستور معمولی رو اجرا کنیم ( داریم از دستور RETURNING استفاده میکنیم تا بعداً چیزی رو ثابت کنیم). برای اینکه مطمئن بشید دادهها ثبت شدن، حالا این دستور رو بزنید:
BEGIN;
INSERT INTO employees (first_name, last_name, start_date, salary, job_title, manager_id, department_id) VALUES ('Elizabeth', 'Christensen', current_date, 1, 'Master of the Highwire', 2, 2) RETURNING employee_id;
COMMIT;
SELECT * FROM employees WHERE first_name = 'Elizabeth' AND last_name = 'Christensen';اما اگر تصمیم بگیرید به جای COMMIT، تراکنش را ROLLBACK کنید، نتیجهای متفاوت خواهید داشت:
BEGIN;وقتی از دستور ROLLBACK استفاده میکنی، مثل این میمونه که داری به پایگاه داده میگی: «بیخیال این تراکنش شو، انگار نه انگار اتفاقی افتاده.» با این کار، هر تغییری که توی تراکنش انجام شده بود، پاک میشه و توی تاریخچه پایگاه داده ذخیره نمیشه. اما یه نکته جالب اینجاست: با اینکه تراکنش ثبت نمیشه، اما پایگاه داده باز هم یه شناسه برای اون تراکنش در نظر میگیره. ولی اگه بعدا بخوای اون رکورد رو با دستور select پیدا کنی، هیچی پیدا نمیشه، چون از اول ثبت نشده بوده!!
INSERT INTO employees (first_name, last_name, start_date, salary, job_title, manager_id, department_id) VALUES ('Chris', 'Winslett', current_date, 1, 'Jr Director of the Highwire', 2, 2) RETURNING employee_id;
ROLLBACK;
SELECT * FROM employees WHERE first_name = 'Chris' AND last_name = 'Winslett';میدونی چرا وقتی یک تراکنش رو شروع میکنی، حتی قبل از اینکه اون رو نهایی کنی، یک مقدار شناسه (ID) بهت برمیگردونه؟
ببین، تراکنشها گروهی از عملیاتهای پایگاه داده هستن که با هم انجام میشن. گاهی اوقات، لازمه که یک مقدار شناسه یکتا برای هر رکوردی که وارد پایگاه داده میکنیم، داشته باشیم. برای این کار، از دنبالهها (sequences) استفاده میکنیم. دنبالهها، مقدار شناسه بعدی رو به صورت خودکار تولید میکنن.
حالا، فرض کن که دو تراکنش همزمان دارن داده وارد پایگاه داده میکنن. اگه هر دو تراکنش از دنبالهای استفاده کنن که هنوز نهایی نشده، ممکنه هر دو تراکنش مقدار شناسه یکسانی رو دریافت کنن. این باعث میشه که دو رکورد با یک شناسه یکسان در پایگاه داده وجود داشته باشن. این کار درست نیست و میتونه باعث مشکلاتی بشه.
برای جلوگیری از این مشکل، دنبالهها حتی قبل از اینکه تراکنش نهایی بشه، مقدار شناسه بعدی رو تولید میکنن. این کار باعث میشه که هر دو تراکنش مقدار شناسه متفاوتی رو دریافت کنن.
حالا، اگه تراکنش رو نهایی نکنی، مقدار شناسهای که بهت برمیگردونه، فقط یک مقدار موقتی هست. این مقدار تا زمانی که تراکنش نهایی بشه، در پایگاه داده ذخیره نمیشه.
اگه تراکنش رو با دستور ROLLBACK لغو کنی، مقدار شناسهای که بهت برمیگردونده، از بین میره.
برای اینکه مطمئن بشی که مقدار شناسهای که دریافت میکنی، در پایگاه داده ذخیره شده، باید تراکنش رو با دستور COMMIT نهایی کنی.
اگه در حین انجام تراکنش، خطا رخ بده، نمیتونی اون رو نهایی کنی. در این صورت، مقدار شناسهای که دریافت میکنی، در پایگاه داده ذخیره نمیشه.
BEGIN;بعد از اجرای دستور بالا، یک دستور ROLLBACK نشان داده خواهد شد. بنابراین، دستور COMMIT ناموفق بوده است زیرا آخرین وضعیت تراکنش یک خطا است.
INSERT INTO employees (first_name, last_name) VALUES ('Tom', 'Jones') RETURNING employee_id;
COMMIT;
#postgresql
@Code_Crafters
👍2