PDA

View Full Version : استفاده از تراکنش



parnian
یک شنبه 07 فروردین 1384, 17:36 عصر
من از mysqlMySQL 4.0.21 استفاده می کنم .می خوام table هام رو به innodb تبدیل کنم تا بتونم از تراکنش استفاده کنم و وقتی که مثلا یک سری عملیات حذف یا ورود داده به روی جداولم صورت می گیره باید این داده ها مثلا روی 3 تا جدول تغییر کنه پس اگر روی یک جدول عملیات انجام شد و وقتی می ره رو جدول بعدی به هر دلیلی برنامه با مشکل مواجه بشه و از ادامه عملیات صرفنظر بشه باید داده های جدولی هم که تغییر کرده درست شه در یک کلام یا کل عملیات انجام شه یا اصلا انجام نشه .دقیقا به من بگید باید چی کار کنم .ممنون

oxygenws
یک شنبه 07 فروردین 1384, 23:51 عصر
با چیزی غیر از innodb هم ممکنه بشه روشی پیدا کرد. من با استفاده کردن از innodb مخالفم، چون هم فشار زیادی به سرور و بالطبع سایت خودتون میاره و دیگه اینکه رو اکثر سرور ها قابل اجرا نیست و اگر هم باشه، ممکنه سایتتون شامل هزینه اضافی بشه.

مسلما خیلی خوب بود که این روند سمت بانک انجام بشه، اما با کمی تغییرات و فکر می شه سمت برنامه این عمل رو شبیه سازی کرد.

موفق باشید

parnian
دوشنبه 08 فروردین 1384, 08:46 صبح
راهنمایی شما خیلی گنگ بود اگر می شه هر دو روش رو توضیح بدید

sirbijan
دوشنبه 08 فروردین 1384, 09:31 صبح
سلام

نه امید خان، نه تنها من کاملا با حرف شما مخالفم، بلکه خیلی های دیگه هم مخالفن! تو چطور میتونی عملیاتی مثل transaction و table locking را با اطمینان بیاری تو برنامه؟ اگر تا حالا با یک بانک پولی کار کرده باشی متوجه هستی قطعا که کار کردن با یک دلار چقدر سخته، چه برسه به اینکه بخوای چند هزار دلار را جا به جا کنی با این اطمینان که همه چی درست انجام میشه! من دو تا پروژه آخری که داشتم کامل با innodb کار کردم (البته تنها table هایی که به این قضیه نیاز داشتن) و خوب خیلی خیلی هم راضیم. شما باید بانک اطلاعاتیت را طوری طراحی کنی که اگر کسی مستقیم باهاش کار کرد کار کنه! ببین PHP که ما می نویسیم دقیقا حکم interface را داره، عینا مثل کاری میمونه که یک graphic designer انجام بده، اون رو کد شما interface میزنه، شما رو database. اگر mysql همین innodb را نداشت اصلا نمیشد باهاش کار کرد. بابت فشاری هم که رو server میاد خوب دیگه کاریش نمیشه کرد، باید بیاد! در ضمن خودت میدونی که یکی از بزرگترین و بهترین تفاوتهای mySql به MS-SQL اینه که مثل برنامه های open source دیگه شما را محدود نمیکنه که حتما باید فلان کار را انجام بدی و یا فلان امکانات را داشته باشی. شما تو یک database که طراحی میکنی، شاید فقط چند تا از جدول ها نیاز به relation و یا transaction داشته باشن که این کاملا منطقی و واجب الاجراست!

پرنیان جان، شما برای اینکه بتونی innodb کار کنی اولا که باید innodb نصب داشته باشی. این را هم خیلی راحت میتونی تو phpMyAdmin موقع ساخت table جدید بفهمی، یا اینکه بعد از اجرای mysql این دستور را تایپ کنی:



SHOW innodb STATUS


اگر هیچ row ای برات برنگردوند یعنی نصب نیست! ولی اگر برگردوند یعنی نصب هست!

innodb خیلی امکانات بهت میده، اگر بخوای روی دو تا table رابطه تعریف کنی، خیلی راحت میتونی اینها را بهم ربط بدی و خوب دیگه از طریق برنامه چک نکنی مثلا id جدول parent وجود داره یا نه! برای اینکه راحت بتونی با این امکانات کار کنی توصیه می کنم جدول خود phpMyAdmin را براش درست کنی و اونو تو فایل conf ش تعریف کنی. اینطوری phpMyAdmin بهت اجازه میده که بصورت گرافیکی رابطه هات را تعریف کنی. البته دستی هم میتونی اینکار را بکنی. یعنی اگر مثلا یک جدول child داری که میخوای به جدول parernt اشاره بکنه و هر دو اینها را innodb تعریف کردی و کلیدهای primary و foreign ت هر دو index هستند، کافیه بنویسی:


ALTER TABLE child
ADD CONSTRAINT FOREIGN KEY ('parent_id') REFERENCES parent ('id')


بابت قضیه transaction هم که گفتی کار خواصی نباید بکنی. شما قبل از اینکه query هایی که می خوای برای transaction به سرور بفرستی باید BEGIN WORK را بفرستی به سرور و بعد query هات را بفرستی و در آخر هم یا COMMIT کنی و یا ROLL BACK . فرض کن من بخوام چند تا update یا delete را بصورت transaction انجام بدم، اینکار را میکنم:



switch ( true )
{
case true:
$res = mysql_query("BEGIN WORK");
$res = mysql_query("UPDATE some_table SET some_field = 'something'");
if ( !$res )
break;
$res = mysql_query("DELETE FROM some_table WHERE some_id = 5");
if ( !$res )
break;

# Now that we know everything went fine
$res = mysql_query("COMMIT");
break;
}

ببین من چیکار کردم، من دارم از یک switch استفاده میکنم که هر جا که تشخیص دادم نتایج کارم غلط بوده، راحت break کنم! لازمه بدونی که بصورت default تنظیمات mysql جوری هست که اگر شما transaction را شروع کردی ولی بعدش نه commit کردی و نه roll back ، این خودش roll back در نظر میگیره، به زبون آدمیزاد auto roll back هست! بنابر این من هرجا که بفهمم کارم بد پیش رفته دیگه لازم نیست اونجا roll back کنم، خیلی شیرین میزنم بیرون و هیچی به server نمیفرستم! در آخر که دیدم همه چی درست پیش رفته، اونقت commit می کنم.
اگر سوال دیگه ای هم داشتی در این مورد من در خدمتم. یک توصیه دیگه هم که برات دارم، البته چندان نمیشناسمت (اصلا نمیشناسمت!) ولی معمولا ما درک درستی از transaction ها نداریم، از همون قوانین ACID، اون I وسط خیلی مهمه، که میگه یک transaction کاملا از thread های دیگه Independent هست، یعنی اگر تا شما commit نکردی، thread های دیگه نسبت به تغییراتی که شما دادی کور هستن. بهت حتما توصیه می کنم خود mysql manual را بخون و قبل از اینکه هیچ query بنویسی کامل راجع بهش فکر کن، معمولا transaction ها همیشه اونکاری را که ما فکر می کنیم انجام میدن انجام نمیدن، برای همین ممکنه شما یک برنامه ای بنویسی که یک خطای logical خیلی گنده داشته باشه، خودت فکر کنی کار میکنه، ولی یک روز بفهمی کار نمیکنه که دیگه خیلی دیر شده باشه! قبل از اینکه رو table های گندت transaction پیاده کنی، حتما رو table های کوچیک تست اینکار را بکن و وقتی فهمیدی که واقعا کاری را که میخوای انجام میده، اونوقت پیادش کن.

oxygenws
دوشنبه 08 فروردین 1384, 14:55 عصر
سلام بر بیژن عزیز :)
حاجی، صحبت الان فقط روی transaction هاست و همونطور که گفتم، مسلما این خیلی خوب بود که اینطور کارها سمت بانک انجام بشه. اما من شخصا، فعلا مخالفم!! ما اینجا از row locking یا ... صحبت نمی کنیم :)

transaction های innodb رو می شه تا حدود بسیار زیادی با برنامه نویسی انجام داد. البته خیلی بستگی داره که قراره چه کارهایی انجام بشه.
مثل برگردوندن مقدار های حذف شده بعد از تراکنش ناموفق بعدی. یا ساختن جداول موقت در حافظه (برای سرعت بیشتر) و اعمال تغییرات روی اونها و سپس اعمال همه همزمان روی بانک یا ....
(یه سوال دارم، می دونی دقیقا سیستم recovery موجود در innodb چیه؟؟ :) آیا نمی شه اون سیستم رو شبیه سازی کرد؟؟)


شما باید بانک اطلاعاتیت را طوری طراحی کنی که اگر کسی مستقیم باهاش کار کرد کار کنه! ببین PHP که ما می نویسیم دقیقا حکم interface را داره، عینا مثل کاری میمونه که یک graphic designer انجام بده، اون رو کد شما interface میزنه، شما رو database.
بانک اطلاعاتیت رو باید چنین طراحی کنی، ولی در صورتی که امکاناتش باشه یا کلا صرف کنه :)
در مورد PHP و interface باهات مخالفم، در حقیقت برنامه باید اونقدر درست باشه که طرف لازم نباشه به غیر از اون برنامه با چیز دیگه ای تمایل پیدا کنه با بانک کار کنه.

parnian
دوشنبه 08 فروردین 1384, 15:37 عصر
ممنون از بابت توضیحات
من در phpmyadmin نوشتم SHOW innodb STATUS و جوابی که به من ارسال شد این بود 050328 15:4... و من نمی دونم این یعنی چی ؟
آیا این به معنای این هست که من innodb دارم؟
من یک سری جدول از قبل طراحی شده دارم که اینا رو خیلی ساده در phpmyadmin ساختم حالا می خوام اینا رو به جدول هایی با تایپ innodb تبدیل کنم و این خط رو در قسمت اس کیو ال phpmyadminمی نویسم که خطا می ده
ALERT TABLE edu_stand TYPE-InnoDB;
می خوام بدونم مشکل چی هست؟

parnian
دوشنبه 08 فروردین 1384, 15:59 عصر
این همون خطایی هست که در هنگام اجرای دستور که گفتم ارسال می شه

#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALERT TABLE edu_stand TYPE-InnoDB' at line 1

وقتی هم که دستور status روکه گفتید در mysql.exe می نویسم خط بعدی رو اینطوری می نویسه <-
اگر که من innodb ندارم چطوری باید نصبش کنم با توجه به اینکه ورژن MySQL 4.0.21

sirbijan
دوشنبه 08 فروردین 1384, 19:39 عصر
سلام
پرنیان جان ALERT نیست دلبندم، ALTER هست! بعد هم که لازم نیست اینکار را بکنی اگر میخوای گرافیکی کار کنی همون phpMyAdmin اینکار را برات میکنه. اگر table ای داری که میخوای تبدیل کنی که table ات را بیار و از بین tab های بالا گزینه Operations را انتخاب کن و از اونجا table type را عوض کن. خب، از همینجا اصلا میتونی بفهمی innodb داری یا نه، اگر تو اون کامبو باکسی که برات باز میشه گزینه innodb باشه، یعنی داری، اگر نباشه؟!

سلام بر امید کبیر، از این به بعد منو عمو بیژن صدا کنید لطفا. امید جان، لطف کن یک سری به سایت خود mysql.com بزن، یک سری مقاله در این باره هست. در مورد پیاده کردن ساختار transaction با php که خودمون یک برنامه کامل نوشته باشیم که طرف فقط از برنامه ما استفاده بکنه، بهت توصیه می کنم حتما با php یک سیستم عامل هم بنویسی که کارت خیلی تکمیل شده باشه! میدونی چقدر قشنگ میشه؟ یک جنبش میشه راه انداخت، با یک زبون اسکریپتی نوشتن یک سیستم عامل کار هر کسی نیست! اگر اونجا مشهد بودم این مطلب را یک جوری تو کلت میکردم که موافقتت یا مخالفتت با اون قضیه php مثل interface میمونه تقریبا هیچ فرقی نمیکنه، چون خیلی ها باهاش موافقن، ولی فعلا تا تابستون که بیام اونجا به اینطور فکر کردن میتونی ادامه بدی! هی، چرا دیگه iranphp نمیای خائن؟

من چند روزی پشت سیستمم نیستم، اگر دیر جواب دادم پیشاپیش عذر خواهی میکنم.

parnian
سه شنبه 09 فروردین 1384, 19:05 عصر
برنامه من به صورت یک تابع بازگشتی کار میکنه آیا وقتی
$res = mysql_query("BEGIN WORK");
و
$res = mysql_query("COMMIT");
break;
رو بنویسم و کل عملیات رو در بین این دو تا قرار بدم همونطوری که من می خوام کار پیش میره .اصولا در یک عملیات بازگشتی تراکنش چطوری عمل می کنه؟
هر جایی که دچار مشکل شد کل داده های قبلی رو برگشت میده؟

oxygenws
سه شنبه 09 فروردین 1384, 19:14 عصر
از زمان BEGIN WORK تا زمانی که COMMIT یا ROLLBACK ارسال کنید.


عمو بیژن، نظرت رو در مورد حرفم نگفتی، موافقم یا مخالفت یا ...

transaction های innodb رو می شه تا حدود بسیار زیادی با برنامه نویسی انجام داد. البته خیلی بستگی داره که قراره چه کارهایی انجام بشه.
مثل برگردوندن مقدار های حذف شده بعد از تراکنش ناموفق بعدی. یا ساختن جداول موقت در حافظه (برای سرعت بیشتر) و اعمال تغییرات روی اونها و سپس اعمال همه همزمان روی بانک یا ....

sirbijan
چهارشنبه 10 فروردین 1384, 00:44 صبح
سلام

پرنیان فکر می کنم به اندازه کافی برات توضیح داده باشم. شما برو به سایت mysql.com قسمت آموزشی (مقالات یا تو همین مایه ها) اونجا میتونی چند تا مقاله خیلی کامل در این باره پیدا کنی. من خودم هم از اونجا خوندم. البته نگاه به سایتهایی مثل phpKitchen.com و DevShed.com هم میتونه خیلی خوب باشه. باور کن هر چی بیشتر بهت بگم فایده ای نداره، تو باید خودت کار کنی تا ریتم بیاد تو بدنت، این در مورد یاد گیری همه چیز صدق میکنه.

امید جان من همونطور که گفتم کاملا مخالفم! نیازی به بحث هم نمی بینم بهر حال هر کسی یکجوری راحتتره و کار میکنه، ولی خب مفاهیم اولیه database design را که می خونی می بینی همه چیز باید در سطح db انجام بشه. البته فکر می کنم تو خودت این را از من بهتر میدونی، پس راجع به چی بحث کنیم؟! بعلاوه که transaction را به هیچ عنوان نمی تونی در هیچ سطحی غیر از خود بانک اطلاعاتی پیاده کنی، چون ممکنه اصلا کد PHP ت وسط برگردوندن حالت database به حالت قبل از اجرای query بترکه، میدونی که چی میگم؟! ولی خود mySql گارانتی میکنه که حتی اگر از کار بیفته وقتی دوباره برگرده کار را از نوع شروع میکنه. کلا یک گارانتی داشتن خیلی خوبه، مثل اینکه من گارانتی hosting خودم را از تو میخوام، ممکنه حتی خودم خدای اینکار باشم، ولی وقتی تو داری فراهم میکنی خب مگه من مریضم که دخالت بکنم؟!

oxygenws
چهارشنبه 10 فروردین 1384, 02:03 صبح
بعلاوه که transaction را به هیچ عنوان نمی تونی در هیچ سطحی غیر از خود بانک اطلاعاتی پیاده کنی، چون ممکنه اصلا کد PHP ت وسط برگردوندن حالت database به حالت قبل از اجرای query بترکه، میدونی که چی میگم؟!
:) مطمئنی مهندس؟؟
از اون عبارت "به هیچ عنوان" ات خوشم نیومد :) همیشه احتمال درست فکر نکردن ما هست. و من فکر کنم راهی باشه :)

sirbijan
پنج شنبه 11 فروردین 1384, 19:16 عصر
آره، همیشه احتمالش هست!