PDA

View Full Version : سوال: مفهوم Rollback در تراکنش



csharpcollegian
سه شنبه 04 اسفند 1394, 08:40 صبح
عرض سلام و وقت به خیر خدمت دوستان و اساتید محترم
عزیزان لطف کنید یه نگاه به این کد بندازید و به سوالاتم پاسخ بدید لطفا

using(SqlConnection Con = new SqlConnection(ConString))
{
SqlCommand Cmd = new SqlCommand();
Cmd.Connection = Con;
Cmd.CommandText = cmdCommand;
Cmd.CommandType = cmdType;
SqlTransaction Trans;
Con.Open();
Trans = Con.BeginTransaction();
Cmd.Transaction = Trans;
try
{
Cmd.ExecuteNonQuery();
Trans.Commit();
}
catch
{
Trans.Rollback();
}
}
آیا کلاس Transaction رو درست پیاده سازی کردم ؟
کوئری ای که در این قطعه کد اجرا میشه از سه INSERT تشکیل شده که INSERT سوم نام جدول رو اشتباه میده و در نتیجه استثنا تولید میشه و هیچ کدام از کوئری ها رو دیتابیس تاثیری نمیذارن، تا اینجاش کاملا درسته
اما مشکل من اینه، حتی زمانی که Rollback رو نمیذارم هم برنامه درست اجرا میشه و جلوی تاثیرگذاری دو INSERT اول روی دیتابیس گرفته میشه
پس کار RollBack چیه ؟ فایده ی نوشتنش توو این کد چیه که حتی اگه نباشه هم کلاس Transaction کارش رو درست انجام میده ؟
چیزی که من فهمیدم اینه که همه چی به دستور Trans.Commit بستگی داره و حتی اگه یک کوئری درست اجرا نشه، Trans.Commit با اجرا نشدنش جلوی تاثیر روی دیتابیس به صورت ناقص رو می گیره، پس Rollback چه کاری می کنه دقیقا ؟
خیلی ممنون

pbm_soy
سه شنبه 04 اسفند 1394, 15:22 عصر
من کد شما را بررسی نکردم !
کلاس trnsaction ندیدم !
در هر صورت rollback میاد تمام کارهای انجام شده از زمان شروع تراکنش را به حالت اول برمیگرداند و تمام دستورات اجرا شده از زمان شروع تراکنش بی اثر میکند
هدف برنامه نویس در اینجا سعی میکند دستورات sql را اجرا کند اگر موفقیت آمیز بود که بلافاصله آتراکنش را commite میکند البته برای بررسی موفقیت آمیز بودن راه های دیگری هم بغیر از نوشتن در try میتواند باشد
ولی در این کد اگر دستورات sql در اجرا خطایی تولید کند بخش catch اجرا میشود یعنی خطا پیسش آمده است پس باید roll back کنید
بازهم میگم روشها زیادی برای این کار وجود دارد

csharpcollegian
چهارشنبه 05 اسفند 1394, 11:29 صبح
با تشکر از جناب pbm_soy ، اساتید محترم کسی نظر دیگه ای نداره...؟

pbm_soy
چهارشنبه 05 اسفند 1394, 19:30 عصر
من نمیخواستم مطلبی بنویسم ولی دیدم دوستان دیگه نظری ندادن گفتم . . . . .!
کد شما را نگاه کردم و سوال شما را هم دقیقتر خواندم حالا باید بگم که
Commit , rollback هر دو لازم هستند اولین دلیل اینه که شما به هر دوی اینها به چشم پایان دهنده یک مجموعه عملیات پیوسته تراکنش درنظر بگیرید حالا یا درست اجرا شدن و یا غلط! تا اگر سری دیگر دستورات اجرا شوند commit و rollback این سری جدید تاثیری به عملیات دستورات سری قبلی نداشته باشد! دلیل دوم و بقیه موارد فکر نمیکنم نیاز باشد چون خودتون میدانید!
برای توضیح بیشتر در همین مثال شما اگر دستورات درست اجرا نشوند وخطا بدهد و شما دبخش catch را خالی گذاشته باشید و در ادامه نیز چند تا دستور sql دیگر گذاشته باشید و اگکر این دستورات به درستی اجرا شده باشند و بدون خطا باشند پس commitی که در انتهای دستورات sql در بلوک try گذاشته اید اجرا خواهد شد و تاثیرات این دستورات جدید و دستورات بخش قبل را همه را نهایی میکند مگر اینکه شما برای این دستورات جدید تراکنش جدیدی تعریف کرده باشید و قبل شروع اجرای دستورات آنرا فعال کرده باشید در اینصورت مشکلی پیش نمیاید واگر rollback هم نکنید چون کامیت نشده آن دستورات اول تا پایان عمر تراکنش نگهداری میشوند و پس پایان عمر تراکنش هم تمام عملیات کامیت نشده بی اثر میشوند

عمل کامیت و رول بک تمام دستوراتی که در تراکنش فعلی قرار دارند را مشخص میکنند تا کامیت و رول بک بعدی بداند که کدام دستورات را باید کامیت کند یا رول بک کند البته بازهم میگم این مورد زمانی است که اگر تراکنش جدیدی تعریف نشده باشد و از همان تراکنش تعریف شده و فعلی و فعال بخواهید استفاده کنید

csharpcollegian
پنج شنبه 06 اسفند 1394, 00:19 صبح
من نمیخواستم مطلبی بنویسم ولی دیدم دوستان دیگه نظری ندادن گفتم . . . . .!
کد شما را نگاه کردم و سوال شما را هم دقیقتر خواندم حالا باید بگم که
Commit , rollback هر دو لازم هستند اولین دلیل اینه که شما به هر دوی اینها به چشم پایان دهنده یک مجموعه عملیات پیوسته تراکنش درنظر بگیرید حالا یا درست اجرا شدن و یا غلط! تا اگر سری دیگر دستورات اجرا شوند commit و rollback این سری جدید تاثیری به عملیات دستورات سری قبلی نداشته باشد! دلیل دوم و بقیه موارد فکر نمیکنم نیاز باشد چون خودتون میدانید!
برای توضیح بیشتر در همین مثال شما اگر دستورات درست اجرا نشوند وخطا بدهد و شما دبخش catch را خالی گذاشته باشید و در ادامه نیز چند تا دستور sql دیگر گذاشته باشید و اگکر این دستورات به درستی اجرا شده باشند و بدون خطا باشند پس commitی که در انتهای دستورات sql در بلوک try گذاشته اید اجرا خواهد شد و تاثیرات این دستورات جدید و دستورات بخش قبل را همه را نهایی میکند مگر اینکه شما برای این دستورات جدید تراکنش جدیدی تعریف کرده باشید و قبل شروع اجرای دستورات آنرا فعال کرده باشید در اینصورت مشکلی پیش نمیاید واگر rollback هم نکنید چون کامیت نشده آن دستورات اول تا پایان عمر تراکنش نگهداری میشوند و پس پایان عمر تراکنش هم تمام عملیات کامیت نشده بی اثر میشوند

عمل کامیت و رول بک تمام دستوراتی که در تراکنش فعلی قرار دارند را مشخص میکنند تا کامیت و رول بک بعدی بداند که کدام دستورات را باید کامیت کند یا رول بک کند البته بازهم میگم این مورد زمانی است که اگر تراکنش جدیدی تعریف نشده باشد و از همان تراکنش تعریف شده و فعلی و فعال بخواهید استفاده کنید


بابت پاسخ کامل و وقتی که گذاشتین ممنونم