PDA

View Full Version : سوال: دستور transacation



Mansoure_c
سه شنبه 23 آذر 1389, 11:04 صبح
سلام،خسته نباشد،كسي ميخواستم بدونم دستور transacation در storde procedure ها در sqlserver چي كار ميكنه؟ اگر توضيح بديد ممنون ميشم.

Rezahak
سه شنبه 23 آذر 1389, 14:31 عصر
دستورات DML یعنی insert و update و delete و ... که دربین begin transaction تا end transaction نوشته می شوند تغییرات را به صورت غیرقطعی روی databse ذخیره میکنند که با commit به تغییرات قطعی شده و با rollback به حالت قبل از transaction بازگردانده می شوند توجه داشته باشید که در طول یک transaction پایگاه داده مورد نظر برای connection های دیگر در حالت lock قرار می گیرد

حمیدرضاصادقیان
سه شنبه 23 آذر 1389, 14:47 عصر
دستورات DML یعنی insert و update و delete و ... که دربین begin transaction تا end transaction نوشته می شوند تغییرات را به صورت غیرقطعی روی databse ذخیره میکنند که با commit به تغییرات قطعی شده و با rollback به حالت قبل از transaction بازگردانده می شوند توجه داشته باشید که در طول یک transaction پایگاه داده مورد نظر برای connection های دیگر در حالت lock قرار می گیرد

البته بهتر بود این شکلی بیان میشد. دستوراتی که بین Transaction قرار میگیرند تضمین میشه که همه اون دستورات اجرا خواهند شد و اگر یکی از اونها اجرا نشه میتوان خطا رو کنترل کرد و کل اعمالی که انجام شده رو به حالت قبل برگردوند.
دراصل Transaction برای تضمین پیاده سازی یک دسته از دستورات هست.

AminSobati
سه شنبه 23 آذر 1389, 19:59 عصر
سلام دوست عزیزم،
یک تراکنش باید چهار خاصیت داشته باشه و منطق "یا همه یا هیچکدام" که دوستان اشاره کردند اصطلاحا Atomic بودن گفته میشه. خواص چهارگانه:
Atomic
Consistent
Isolated
Durable

دستوراتی که مابین شروع و خاتمه تراکنش قرار میگیرند باید قوائد فوق در موردشون رعایت بشه. این رعایت توسط خود SQL Server انجام میشه. شما بعنوان برنامه نویس فقط کافیه از دستور شروع و خاتمه تراکنش در جای صحیح استفاده کنید.
از اونجایی که ویرایشهای ما سبب نگه داشتن Lock روی رکوردها یا جداول میشه، بهتره تراکنشها رو تا جای ممکن کوتاه مدت باز کنیم.
ضمنا وقتی دستورات ویرایشی شما مجزا هستند و ارتباطی به هم ندارند، نیازی نیست از دستور شروع تراکنش استفاده کنید

m_omrani
چهارشنبه 24 آذر 1389, 21:44 عصر
حال که بحث به طور کلي درباره تراکنشه، اجازه می خوام من هم یک سوال مطرح کنم:

1. آيا در SQL Server امکاني وجود داره که تراکنش بين چند Connection انجام بشه. مثلاً يکي شروع کنه و ديگري عمليات رو Commit یا Rollback کنه (به عنوان مثال عملی، فرض کنید دو صفحه یا فرم جدا در برنامه تون دارید. یکی عملیاتی رو شروع می کنه، اما لزوماً اتمامش توسط خودش انجام نمی شه. سپس فرم یا صفحه دیگری باز می شه که در اونجا هست که به طور قطع معلوم می شه عملیات باید Commit بشه یا Rollback).

ضمن تشکر پیشاپیش از پاسخ تون به سوال بالا باز هم اجازه می خوام یک سناریوی پیچیده رو هم مطرح می کنم فکر می کنم مفید باشه:

فرض کنید در SQL Server خودمون یک Linked Server به دیتابیس دیگه ای ایجاد کردیم (دقت کنید این دیتابیس می تونه هر چیزی باشه). حال در یک اسکریپت T-SQL به نظر شما آیا می تونیم تراکنشی رو شروع کنیم که برای مجموعه دستوراتی قرار باشه انجام بشه که هم دیتابیس خودمون و هم دیتابیس Linked Server رو دستکاری می کنه؟ در این حالت آیا باز هم خواص ACID که مهندس ثباتی بهش اشاره کردن برقرار می مونه؟ یعنی آیا وقتی عملیات Rollback می شه (چه به طور دستی توسط ما و یا توسط خود سرورها به هر دلیلی)، آیا تغییرات هم در دیتابیس خودمون و هم در Linked Server برگردونده می شه؟

در مورد این مطلب پاسخ مثبته و به چنین چیزی تراکنش توزیع شده یا distributed transaction گفته می شه. برای شروع چنین تراکنشی باید از BEGIN DISTRIBUTED TRANSACTION استفاده کرد. مدیریت کل عملیات هم توسط MS DTC (Microsoft Distributed Transaction Coordinator) انجام می شه. خواص ACID هم کاملاً حفظ می شه، چه در غیر این صورت اصلاً تراکنش معنی نداره.

به نظرم به عنوان نمونه ای از این سناریو می شه به بانک های عضو سیستم شتاب اشاره کرد. البته من نمی دونم دیتابیس شون چیه، اما سناریو همانا سناریوی «تراکنش های توزیع شده» است.

از توجهتون ممنونم.

bestirani2
پنج شنبه 25 آذر 1389, 10:04 صبح
حال که بحث به طور کلي درباره تراکنشه، اجازه می خوام من هم یک سوال مطرح کنم:

1. آيا در SQL Server امکاني وجود داره که تراکنش بين چند Connection انجام بشه. مثلاً يکي شروع کنه و ديگري عمليات رو Commit یا Rollback کنه (به عنوان مثال عملی، فرض کنید دو صفحه یا فرم جدا در برنامه تون دارید. یکی عملیاتی رو شروع می کنه، اما لزوماً اتمامش توسط خودش انجام نمی شه. سپس فرم یا صفحه دیگری باز می شه که در اونجا هست که به طور قطع معلوم می شه عملیات باید Commit بشه یا Rollback).

تا اینجا که من میدونم همچین چیزی امکان پذیر نیست ولی شما خودتون میتونید یک جدول اولیه درست کنید و وقتی فرد دوم میاد علاوه بر اطلاعات مربوط به اون فرد اطلاعات مربوط به فرد اول رو هم از جدول اولیه به ثانویه انتقال بده که در نهایت اگه موفق نشد به عقب بر گردونه و اطلاعات رو از جدول اولیه پاک کنه

AminSobati
پنج شنبه 25 آذر 1389, 23:47 عصر
یک تراکنش همیشه توسط یک Session یا SPID مدیریت میشه. ولی مثال فرم رو که مطرح کردین نکته انحرافی داره! چون در ADO میتونین تراکنش رو در یک فرم باز کنین و وقتی Connection هنوز بازه، در فرم دیگه ای Commit کنین. پس ملاک فرم یا Application نیست، بلکه Session هست.
در خصوص Distributed Transaction، تنها زمانی DTC میتونه ACID رو تضمین کنه که دیتابیس مقصد اساسا تراکنش رو بشناسه. مثلا Distributed Transaction روی Access نمیتونین داشته باشین، ولی روی Oracle چرا.

saeed_r67
جمعه 26 آذر 1389, 01:07 صبح
من تا حالا با transacation کار نکردم . میشه بگید کجا نوشته میشه و چه جوری توسط vb6 فراخوانی میشه؟
ممنون میشم اگه توجه کنید.

AminSobati
جمعه 26 آذر 1389, 09:23 صبح
توصیه میکنم تراکنش رو از سمت کلاینت باز نکنین، ولی به هر حال برای اینکه سوال شما رو پاسخ داده باشم، با متد BeginTransaction از آبجکت Connection

saeed_r67
جمعه 26 آذر 1389, 13:45 عصر
توصیه میکنم تراکنش رو از سمت کلاینت باز نکنین، ولی به هر حال برای اینکه سوال شما رو پاسخ داده باشم، با متد BeginTransaction از آبجکت Connection

ممنون.
ولی یه سوال:
منظورتون از این که :(تراکنش رو از سمت کلاینت باز نکنم) چیه؟
آا منظورتون تشکیل صف و فرستادن به server هست؟
اگه بیشتر توضیح بدید ممنون میشم.
اگه مثالتون رو پیرامون بانک ها (بانک ملی، صادرات و...) بزنید ممنون میشم.
باز هم ممنون

saeed_r67
جمعه 26 آذر 1389, 19:20 عصر
البته من فکر نکنم که بانک ها از این روش استفاده کنند.
چون وقتی تراکنشی انجام نمیشه ، در صورتی که از حساب مشتری(خود پرداز ها) کسر شده باشد ، بعد از چند ساعت وجه کسر شده به حساب مشتری واریز می شود .
که از دیدگاه تئوری شخص بنده :
اونا با دستور نویسی این تراکنش ها رو کنترل می کنند ، نه با transacation در sql
اگه برداشت من اشتباست ، تصحیح بفرمایید.

AminSobati
جمعه 26 آذر 1389, 20:55 عصر
ممنون.
ولی یه سوال:
منظورتون از این که :(تراکنش رو از سمت کلاینت باز نکنم) چیه؟
آا منظورتون تشکیل صف و فرستادن به server هست؟
اگه بیشتر توضیح بدید ممنون میشم.
اگه مثالتون رو پیرامون بانک ها (بانک ملی، صادرات و...) بزنید ممنون میشم.
باز هم ممنون

منظور این هست که با دستور BeginTran از ADO تراکنش شروع نکنید، چون ممکنه برنامه به هر دلیلی با مشکل یا کندی مواجه بشه در نتیجه تراکنش به مدت طولانی تری باز خواهد موند و سایر کاربرها Block میشن.
در مورد بانکها، مسلما اصل قوائد چهار گانه تراکنش حفظ میشه اما چگونگی اون بستگی به بانک اطلاعاتی داره. هر بانک اطلاعات با ابزار خودش این کار رو انجام میده