خ
سلام وقت همگی به خیر
دوستان میخواستم بدونم چطور میشه زمانی که به دلیل انجام یک تراکنش نیاز به ثبت و تغییر اطلاعات در چند جدول هست، این کار رو به بهترین روش ممکن انجام داد ؟
روشی که اگر در هنگام ثبت و تغییر اطلاعات برق رفت یا به هر دلیلی ارتباط به صورت ناگهانی با دیتابیس قطع شد تضمین کنه که یا همه ی جدول ها با هم اطلاعاتشون
بروز میشه یا اگر تغییر فقط در چند جدول انجام شده و تعدادی جدول باقی موندن، تغییرات انجام شده تصحیح بشه و به حالت اول برگرده !
دقیقا مثل سیستم بانک که اگه پول از حساب کم بشه ولی خرید انجام نشه، تغییرات انجام شده در حساب تصحیح میشه
فقط ممنون میشم در حد متوسط و قابل فهم توضیح بدین
خیلی ممنون
شخصا متخصص مباحث پایگاه داده ها نیستم، ولی تا اونجایی که اطلاع دارم به این شیوه عمل می کنند :
یک تراکنش بدین صورت مشخص میشه که یک BEGIN TRAN اولش میاد
و هر چی که در ادامه بنویسید داخل بدنه تراکنش قرار می گیره و نهایتا با یکی از دو دستور COMMIT TRAN یا ROLLBACK TRAN تصمیم می گیرید که تراکنش مورد قبول و تایید بشه یا برگردونده بشه به حالت قبل از اجرای تراکنش :
کد:
BEGIN TRAN
.
.
.
COMMIT TRAN
کد:
BEGIN TRAN
.
.
.
ROLLBACK TRAN
هر زمانی که دستوری اجرا میشه، ROWCOUNT@@ تغییر می کنه، این متغیر می تونه نشون بده که آخرین دستوری که اجرا شد چند تا رکورد رو تحت پوشش قرار داده. بعضی دستورات که کاری با رکورد ندارند
این مقدار رو 0 می کنند و برخی دیگر عدد 1 رو در ROWCOUNT@@ ثبت می کنند. گاهی اوقات از این متغیر برای بررسی عملکرد دستور قبلی استفاده میشه که مشخص بشه کار درست پیش رفته یا خیر.
مثلا شما می خواهید فردی رو از جدول مشتریان حذف کنید که ممکن است قبلا خرید کرده باشد. جدول مشتریان customers است و جدول ده سفارش های مشتری orders است.
وقتی مشخصات مشتری ای را حذف می کنید اطلاعات فردی مشتری حذف می شود اما خرید ها نباید بخاطر حذف مشتری ناپدید شوند پس باید در جدول خرید ها، سفارش دهنده آن خرید ها به مشتری گمنام (شماره id ئه صفر) تغییر کند.
اگر اینکار انجام نشود و بعد مشتری جدیدی از آن id مشتری قبلی استفاده کند خرید های دو مشتری ادغامی می شوند.
طبیعتا نمی توانید تضمین کنید که این مشتری در جدول سفارش ها فلان تعداد خرید داشته اما اگر تراکنش درست انجام شود باید یک رکورد از جدول مشتریان حذف شود.
اگر چنین شد تراکنش درست و قابل قبول است وگرنه تراکنش باید بصورت کامل لغو شود، چه تغییر مشخصات سفارش ها و چه لیست مشتریان.
به سادگی فرض می کنیم که مشتری با id ئه 123 حذف می شود :
کد:
BEGIN TRAN
UPDATE orders SET customerid = 0 WHERE customerid = 123;
DELETE FROM customers WHERE customerid = 123;
IF @@ROWCOUNT = 1
COMMIT TRAN
ELSE
ROLLBACK TRAN
در Net Framework. کلاس SqlTransaction می تواند این کار را به شکل مشخص تری انجام دهد. یک شیء از کلاس SqlTransaction می سازید :
کد:
SqlTransaction transaction = connection.BeginTransaction("MyTransaction");
و دستورات SQL را در اشیاء SqlCommand می نویسید :
کد:
SqlCommand command = connection.CreateCommand();
command.CommandText = "UPDATE orders SET customerid = 0 WHERE customerid = 123;";
و قبل از اجرا به SqlTransaction ای که ساخته اید ربط می دهید :
کد:
command.Transaction = transaction;
command.ExecuteNonQuery();
برای اجرا کردن دستورات بعدی نیازی به ساختن command جدید نیست، می توانید CommandText را عوض کنید و موارد جدیدی را اجرا کنید :
کد:
command.CommandText = "DELETE FROM customers WHERE customerid = 123;";
command.ExecuteNonQuery();
اگر کد درست اجرا شد تراکنش را تایید کنید، به یاد داشته باشید که ExecuteNonQuery تعداد سطر هایی که کوئری تحت تاثیر قرار داده رو بر می گردونه، مثلا عدد 1 را بر می گرداند :
و اگر نتیجه مثبت نبود لغو اش کنید :