PDA

View Full Version : اجرای یک ترانزکشن در دو مکان متفاوت



saeeedft
چهارشنبه 18 آذر 1388, 23:26 عصر
با سلام خدمت اساتید، فرض کنید دوتا دکمه داریم که هر کدام عملیات مخصوصی انجام میدهند(مثلا درج) و در عین حال این عملیات به هم مرتبط نیز هستند، به عنوان مثال مثلا ما میخواهیم یک عمل ثبت انجام دهیم که قسمتی از دادها برای ثبت در دکمه اول و قسمت دیگری از دادها برای ثبت در بانک در دکمه دوم وجود دارد، حالا من میخوام اینو با transaction پیاده سازی کنم، خب اگه قرار بود کل عملیات در یک دکمه انجام بشه که به راحتی میشد transaction رو براش نوشت، اما حالا که عملیات ثبت بین دو دکمه تقسیم شده چه طور میشه این transactin رو پیاده سازی کرد؟ یعنی اگه ثبت توی دکمه دوم انجام نشد ، دکمه اول نیز عملیات ثبت رو انجام نده

sia_2007
پنج شنبه 19 آذر 1388, 01:24 صبح
ببینید؛ در SQL، میتوان حالتی را پیاده سازی کرد که ما بگوییم :
شروع ترن اول
ذخیره موقت ترن اول !
شروع ترن دوم
ذخیره موقت ترن دوم !
حال اگر هر دو ( همه ) موفقیت آمیز بودند : ذخیره دائمی هر دو ( همه ).
متاسفانه الآن ساعت دو شبه و من به کدهام دسترسی ندارم
شرمنده
امیدوارم این همون چیزی باشه که شما میخواهین
کدش رو هم تا عصر پنج شنبه؛ نهایتا میگذارم.

saeeedft
پنج شنبه 19 آذر 1388, 09:02 صبح
اقا منظورم دقیقا همینه، ممنون میشم بیشتر راهنماییم کنید

Hamid.Kad
پنج شنبه 19 آذر 1388, 16:01 عصر
اگر خاصیت تراکنش رو ACID در نظر بگیریم خاصیت آخری (یعنی Durability) به این معناست که پس از commit شدن یک تراکنش، داده ها ماندگارند. در مواردی که شما از تراکنشهای تودرتو (nested Transactions) استفاده می کنید قضیه یه کم فرق میکنه. برای راهنمایی بیشتر توی help Sql server عبارت
Nested Transaction رو جستجو کنید. اگر میتونید از Nested استفاده کنید که فبهاالمراد و نعم المطلوب!
اگر نه که خودتون توی جدول اول کامیت کنید. اگر توی جدول دوم خواستید RollBack کنید، از جدول اول هم Delete کنید.
ولی جسارتاً من احساس میکنم ممکنه یه کم طراحیتون اشکال داشته باشه. میشه بفرمائید دقیقاً چه حالتی پیش اومده که میخواهید این کار رو انجام بدید ؟

sia_2007
پنج شنبه 19 آذر 1388, 22:51 عصر
SET XACT_ABORT ON
BEGIN TRAN
INSERT INTO Customers
(CustomerID, CompanyName)
VALUES (N'ABCDE', N'Moradi')
SAVE TRAN A
DELETE FROM Orders
WHERE OrderID = 1
SAVE TRAN B
COMMIT

---


دوست عزیز؛
من شرایط پیدا کردن کد کامل رو ندارم. تا اطلاع ثانوی البته شرمنده
این کد کار میکنه ؛ ولی خیلی کاملتر از این هم کار میکنه
فی الحال حافظه من تا این حد جواب داد.
---
دوست عزیز؛ حمید جان
متاسفانه در SQL ؛ Nested Tran ها به خوبی جواب نمیدهند.
من با این خیلی کارها میکنم ولی متاسفانه کدشون رو حفظ نیستم.
---
امیدوارم مشکلتون حل شده باشه؛ اگر هم نشده به زودی حل بشه.

Hamid.Kad
جمعه 20 آذر 1388, 00:51 صبح
دستور Save TRAN با چیزی که شما توی پست 2 نوشتید تفاوت داره. در حقیقت این دستور یه SavePoint ایجاد میکنه که سرعت رو بالاتر میبره.


متاسفانه در SQL ؛ Nested Tran ها به خوبی جواب نمیدهند.
منظورتون از اینکه به خوبی جواب نمیدهند چیه ؟
کجاها و تحت چه شرایطی منظورتون هست ؟

sia_2007
جمعه 20 آذر 1388, 02:11 صبح
این برای افزایش سرعت نیست
در واقع جواب مایکروسافت به مشکلات Nested Tran در MSSQL است.
زمانی که با کنترلر خطا ادغام گردد؛ شما میتوانید بگویید حالا که به مشکل خوردی یه تعداد از Save Point ها رو ذخیره کن یا نکن.
این کار سرعت را به علت ساخت و ذخیره چندین Save Point پایین میبرد؛ نه بالا
من در این جا با سوئیچ XACT در واقع کمی کار رو راحت تر کرده ام.
در مورد اشکالات Nested Tran هم با هم حرف میزنیم.

Hamid.Kad
جمعه 20 آذر 1388, 14:34 عصر
این برای افزایش سرعت نیست
اینجا (http://msdn.microsoft.com/en-us/library/ms188378.aspx)رو مطالعه بفرمائید. اگه برداشت من اشتباهه بفرمائید

این کار سرعت را به علت ساخت و ذخیره چندین Save Point پایین میبرد؛ نه بالا
بله، درسته. ولی اگر قرار باشه عمل RollBack اتفاق بیفته خیر. چون دیگه مجبور نیست از اول اجرای تراکنش rollback کنه


در مورد اشکالات Nested Tran هم با هم حرف میزنیم.
گمان میکنم منظور شما در تریگرها یا SP ها هست. درسته ؟

sia_2007
جمعه 20 آذر 1388, 22:06 عصر
البته حرف شما کاملا متینه؛
نوشتن Tran اغلب برای این است که با موفقیت انجام شود؛
و Save بیهوده اون رو کند میکنه.
ولی اگر سناریویی داشته باشیم که در آن مدام تراکنش به مشکل میخورد؛ استفاده از Save Tran ؛ بهترین ایده است.
انجام عمل صحیح در این مورد به آیه شریفه ((بستگی داره)) مربوط میشه.
---
ببینید؛ ابتدا ببینیم ما دچار سوء تفاهم شده ایم یا نه ؟!
من منظورم از Nested Tran چنین چیزی هست :

Begin Tran
دستور 1
BEGIN TRAN
دستور 2
Commit
دستور3
Commit

ببینید؛ اگر تراکنش داخلی به مشکل بخورد و یا دستور Roll Back را خودمان اجرا کنیم :
آخرین Commit به مشکل میخورد؛ و دستور 3 هم بدون تراکنش اجرا میشود؛ که ممکن است کنار دستور 3 ، چند دستور دیگر هم باشند؛ همه بدون Tran اجرا میشوند؛ (البته منظور من با سوئیچ XACT است) ؛ و این مطلوب من نیست.
البته این رو در sp یا Trigger امتحان نکرده ام.
اگر اشتباه میکنم؛ بفرمایید.
چون من این رو 4 ماه پیش امتحان کردم؛ شاید هم اشتباه میکنم.
به نظر خودم استفاده از Save بهتر است.
فکر کنم دوست عزیزمون saeeedft با این راهنمایی که کردم؛ رفت که پشت سرش رو هم نگاه نکنه؛
خوب این کار سختی بود.
امیدوارم که مشکلشون حل بشه.
منتظرم
موفق باشی

saeeedft
شنبه 21 آذر 1388, 00:53 صبح
فکر کنم دوست عزیزمون saeeedft با این راهنمایی که کردم؛ رفت که پشت سرش رو هم نگاه نکنهنه اقا کجا برم، کارم درست نشده که، میدونی مشکل کجاست، توی مثال اولم هم گفتم، شما دو تا دکمه رو در نظر بگیرید، حالا قراره این transaction بین این دو دکمه تقسیم بشه و نتیجه کار یه عمل ثبت کلی هستش یعنی اگه عملیات توی دکمه دوم با موفقیت انجام نشد اطلاعاتی که توسط دکمه اول ثبت شده هم لغو بشه ، اینطور که شما نوشتید امکان اینکه دو ترانزکشن توی دو مکان متفاوت بخواد اجرا بشه(با توجه به این مسئله که این دو با هم ارتباط هم دارند) نمیشه، الان مشکل اصلی اینه که این عملیات توی دو مکان متفاوت قراره اتفاق بیفته اما در عین حال کارهایی که توی این دو مکان انجام میدیم به هم مرتبط هستند

sia_2007
شنبه 21 آذر 1388, 18:29 عصر
خودم هم حدس میزدم؛
این کار شما خیلی مشکله
علت دقیقش میدونی چیه ؟
وقتی شما تو یه Table ؛ مینویسی حداقل یک یا چند رکورد؛ یا حتی کل جدول رو Lock میکنی؛ (بسته به نوع Lock Essential ) جدولتان.
خب حالا فرض کنید اپراتور ؛ دکمه اول رو زده؛ بعد رفته چایی بخوره.
اون منابع Lock میمونند؛ و حتی کسی نمیتواند اونها رو بخونه !
اون وقت باید Read Uncommitted بزنی؛ یا با یک چنین اسمی.
این چیه ؟
این میگه که مقداری رو که قطعی نشده بخون.
تازه Dead_Lock هم ممکنه رخ بده
من میگم این رو با یه ترفندی شبیه سازی کن.
حالا ترفندش به وضعیت سیستم شما مربوطه.
کاش یه کم بیشتر توضیح میدادی.
دوستان نظری ندارند ؟

Hamid.Kad
شنبه 21 آذر 1388, 23:31 عصر
من که بنظرم احتمالاً یه جایی توی طراحی اشکال دارن که همچین حالتی بوجود اومده. میشه دقیقاً بفرمائید چی شده که مجبور شدید این کار رو انجام بدید ؟

saeeedft
یک شنبه 22 آذر 1388, 01:04 صبح
اقا من دوتا فرم دارم که نصف عملیات توی یه فرم و نصف دیگه توی فرم دوم انجام میشه، اما این دوتا فرم به هم وابسته هستند، حالا میخوام اگه توی یک کدوم از این دو عملیات اتفاق نیافتاد توی اون یکی هم اگه قبلا کاری انجام شده لغو بشه

saeeedft
یک شنبه 22 آذر 1388, 22:00 عصر
این کار شدنی هست یا نه؟؟؟؟؟؟؟؟؟؟

sia_2007
یک شنبه 22 آذر 1388, 23:11 عصر
شما میدونید Lock شدن دیتا به مدت طولانی یعنی چی ؟
من اگر بودم به هر نحوی بود این رو شبیه سازی میکردم.
دقیقا شما چه نیازی دارید ؛ که دکمه اول واقعا اجرا شود ؟
آیا از نتیجه اش در دومی استفاده میکنی ؟

Hamid.Kad
یک شنبه 22 آذر 1388, 23:12 عصر
دوست عزیز. شما مرتب حرف خودتون رو تکرار میکنید. من میدونم که شما دو تا دکمه یا فرم دارید و ....
بنده عرض کردم بفرمائید چرا این کار رو میکنید ؟ یعنی صورت مساله چی بوده که شما اینجوری حلش کردید؟
اگه کامل توضیح بدید فکر کنم بقیه دوستان هم کمک بیشتری خواهند کرد

saeeedft
دوشنبه 23 آذر 1388, 01:07 صبح
اقا ببینید، فرض کنید ما پرداخت پولمون به صورت نقدی ، چکی حالا اگه کاربر چکی رو انتخاب کنه یه صفحه باز میشه و اطلاعات مربوط به چک توش نوشته میشه، حالا اگه کاربر صفحه چک رو باز کنه و اونو ببنده و توی صفحه اول اطلاعات رو وارد کنه(خواسته یا ناخواسته) توی دیتا بیس نوع پرداخت چکی انتخاب شده اما هیچ اطلاعاتی مربوط به چک توش ثبت نشده، خودمم فکر کنم به این طریق نشدنی هستش، حالا اگه راه حلی هست ممنون میشم راهنماییم کنید