خانه SQL Server آشنایی با Isolation Level در SQL Server SQL Server افزایش سرعت SQL Server نوشته شده توسط: مسعود طاهری تاریخ انتشار: ۲۷ آبان ۱۳۹۳ آخرین بروزرسانی: 17 آذر 1403 زمان مطالعه: 8 دقیقه ۴.۱ (۲۵) Isolation Level در SQL Server، در یکی از مقالههای سایت توضیحاتی در مورد تراکنشها (مدیریت تراکنش ها) ارائه شده است. در این مقاله در مورد Isolation Levelهای تراکنشها صحبت خواهیم کرد. در ابتدا تعریفی از Isolation Level را میآوریم. Isolation Levelها در SQL Server روشهای قفل گذاری در میان چند تراکنش را مشخص میکند. به بیان ساده تر اگر ما یک عمل به روز رسانی را داخل یک تراکنش انجام دهیم و از طرف دیگر با استفاده از دستور SELECT داده های مربوط به همان به روز رسانی را بخواهیم استخراج کنیم، اینجا Isolation Level نحوه دستیابی ما به اطلاعات را مشخص خواهد کرد. در ادامه این مقاله هر مورد از انواع Isolation Level همراه با یک مثال توضیح داده شده است. قبل از شروع بحث لازم است تا یک دیتابیس جدید و جدولی را به عنوان نمونه ایجاد نمایید. شما میتوانید علاوه بر مطالعه این مطلب، با رجوع به مقاله آموزش SQL Server ، سایر مباحث مهم مربوطه را به زبان ساده و با جزئیات بیاموزید. CREATE DATABASE IsolationLevelTest GO CREATE TABLE TestTable ( ID int IDENTITY, Field1 INT NULL, Field2 INT NULL, Field3 INT NULL ) GO INSERT INTO TestTable (Field1,Field2,Field3) VALUES (1,2,3) INSERT INTO TestTable (Field1,Field2,Field3) VALUES (1,2,3) INSERT INTO TestTable (Field1,Field2,Field3) VALUES (1,2,3) INSERT INTO TestTable (Field1,Field2,Field3) VALUES (1,2,3) مفهوم Isolation Level در SQL Server در این بخش از آموزش قرار است، مفاهیمی را برای شما توضیح بدهیم. با ما همراه باشید: ۱- مفهوم Dirty Reads فرض کنید تراکنشی باعث تغییر اطلاعات در بدنه خود شده است ولی هنوز آن تراکنش Commit نشده است. اگر شرایط به گونهای باشد که با استفاده از دستور Select دادههای تغییر یافته معلق را که هنوز تایید نشده است را استخراج نماییم و آنها را مشاهده کنیم اصطلاحا به آن Dirty Read گفته میشود. ۲- مفهوم Phantom Reads اگر حین انجام Select داخل یک تراکنش، اطلاعات جدیدی در دیتابیس درج شود و این درج اطلاعات روی نتیجه Select ما تاثیر بگذارد (سطرهای جدید به نتیجه Select اضافه شود) اصطلاحا گفته میشود که Phantom Read اتفاق افتاده است. در ادامه مقاله این موضوع به صورت عینی توضیح داده شده است. انواع Isolation Level Read UnCommitted Read Committed Repeatable Read Serializable Snapshot ۱- مفهوم Read Uncommitted این سطح ارزیابی به نوعی پایین ترین سطح ارزیابی میباشد به طوری که هیچ قفلی بر روی رکوردها اعمال نمیشود. مثلا اگر اطلاعاتی را داخل یک تراکنش به روزرسانی مینمایید یک تراکنش دیگر میتواند این اطلاعات را تغییر دهد. یا اگر در حال اجرای تراکنش، یک دستور Select بنویسید اطلاعاتی را دریافت کنید که هنوز تایید و نهایی نشده است. با این اوصاف میتوان گفت اطلاعاتی که در این Selectها به دست میآید به احتمال زیاد نامعتبر خواهد بود. همان Dirty Read در اینجا اتفاق خواهد افتاد. یک مثال: یک صفحه New Query باز کنید و دستور زیر را در آن کپی نمایید BEGIN TRAN UPDATE TestTable SET Field1 = 2 WAITFOR DELAY '00:00:10' ROLLBACK یک صفحه New Query دیگر باز کنید و دستور زیر را در آن کپی نمایید SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT * FROM TestTable دستورات اول را اجرا کرده و سریع دستورات دوم را اجرا نمایید. خروجی مانند زیر خواهد بود. 10 ثانیه منتظر بمانید و دوباره دستورات دوم را اجرا کنید. این بار خروجی متفاوت خواهد بود. مانند شکل زیر. همان طور که می بینید در اولین اجرای دستورات دوم، اطلاعاتی را به دست آوردیم که تغییر یافته بود ولی هنوز نهایی نشده بود. در واقع Dirty Read اتفاق افتاد. ۲- مفهوم Read Committed این سطح ارزیابی سطح پیش فرض SQL Server میباشد. در این حالت اطلاعاتی که داخل یک تراکنش باشد تا لحظه اتمام آن تراکنش به حالت قفل در خواهد آمد. یعنی نه میتوان آن ها را Select کرد و نه میتوان آن ها را تغییر داد یا حذف کرد. چنانچه دستور SELECT شما همزمان با اجرای تراکنش باشد اجرای دستور SELECT منتظر اتمام تراکنش خواهد ماند. با یک مثال بهتر متوجه خواهید شد. یک صفحه New Query باز کنید و دستورات زیر را در آن کپی نمایید BEGIN TRAN UPDATE TestTable SET Field1 = 2 WAITFOR DELAY '00:00:10' ROLLBACK یک صفحه New Query دیگر باز کنید و دستورات زیر را در آن کپی نمایید SELECT * FROM TestTable همانند مثال قبل ابتدا دستورات اول را اجرا کنید و سپس سریع دستورات دوم را اجرا نمایید. همان طور که میبینید نتیجه خروجی دستور دوم با تاخیر نمایش داده خواهد شد. و این به خاطر تاخیر در اتمام تراکنش در دستورات اول میباشد. ۳- مفهوم Repeatable Read این سطح ارزیابی شبیه Read Committed می باشد ولی با این تفاوت که Repeatable Read این تضمین را به ما میدهد که تمامی دستورات تغییر اطلاعاتی، که شما آن ها را Select کردهاید منتظر خواهد ماند تا Select شما به اتمام برسد. با یک مثال بهتر متوجه خواهید شد: یک صفحه New Query باز کنید و دستورات زیر را در آن کپی نمایید SET TRANSACTION ISOLATION LEVEL REPEATABLE READ BEGIN TRAN SELECT * FROM TestTable WAITFOR DELAY '00:00:10' SELECT * FROM TestTable ROLLBACK یک صفحه New Query دیگر باز کنید و دستورات زیر را در آن کپی نمایید : UPDATE TestTable SET Field1 = 7 همانند مثال های قبل ابتدا دستورات اول را اجرا نموده و سپس سریع دستورات دوم را اجرا نمایید. خروجی دستورات اول به شکل زیر خواهد بود. همان طور که مشاهده می کنید دستور Update که اجرا شده است تاثیری در خروجی Selectهای ما نداشته و خروجی هر دو Select شبیه هم میباشد. اگر در دستورات اول Isolation Level را به Read Committed تغییر دهید خروجی Selectها شبیه هم نخواهد بود. به عبارتی دستور Update منتظر اتمام دستورات اول نخواهد ماند. پیشنهاد میکنیم برای درک بهتر مفاهیم دوره کوئری نویسی پیشرفته را مطالعه کنید. نکته : اگر در حین تراکنش با سطح ارزیابی Reapeatable Read دستور Insert در جدول مربوطه اجرا شود و دادههای جدید اضافه شود، Phantom Read اتفاق خواهد افتاد. یعنی در خروجی آخرین Select سطرهای اضافه شده نیز نمایش داده خواهد شد. ۴- مفهوم Serializable این سطح ارزیابی شبیه Repeatable Read می باشد منتها Serializable یک تضمین اضافی را نیز به ما میدهد که اجازه درج رکورد جدید در اطلاعات مربوطه را تا اتمام تراکنش نخواهد داد. بنابر این جلوی Phantom Read نیز گرفته خواهد شد. با یک مثال بهتر متوجه موضوع خواهید شد. یک صفحه New Query باز کنید و دستورات زیر را در آن کپی نمایید. SET TRANSACTION ISOLATION LEVEL SERIALIZABLE BEGIN TRAN SELECT * FROM TestTable WAITFOR DELAY '00:00:10' SELECT * FROM TestTable ROLLBACK یک صفحه New Query دیگر باز کنید و دستورات زیر را در آن کپی نمایید. INSERT INTO TestTable(Field1,Field2,Field3) VALUES (100,100,100) مانند مثالهای قبلی ابتدا دستورات اول را اجرا کرده و سپس سریع دستورات دوم را اجرا نمایید. خروجی مانند زیر خواهد بود همان طور که مشاهده می کنید خروجی هر دو Select شبیه هم میباشد. بنابر این دستور Insert که در دستورات دوم نوشته شده است منتظر اتمام تراکنش در دستورات اول مانده است. Snapshot : این سطح ارزیابی دقیقا مشابه Serializable میباشد با این تفاوت که Snapshot عملیات Update و Insert را قفل نخوهد کرد. شاید این سوال به ذهنتان برسد که تغییر اطلاعات چگونه مدیریت میشود؟ پاسخ این است که اگر عملیاتی بعد از Snapshot بر روی دادهها تغییراتی را ایجاد کنند یا داده های جدیدی در دیتابیس ثبت شوند این تغییرات و دادههای جدید در tempdb ذخیره خواهد شد. ضمنا یک Row Version هم به این اطلاعات اضافه میشود. بعد از اتمام تراکنش Snapshot، آخرین اطلاعات از tempdb به دیتابیس شما منتقل خواهد شد. برای فعال سازی این Isolation Level بایستی دستور زیر را اجرا نمایید. ALTER DATABASE IsolationLevelTest SET ALLOW_SNAPSHOT_ISOLATION ON یک صفحه New Query باز کنید و دستورات زیر را در آن کپی نمایید. SET TRANSACTION ISOLATION LEVEL SNAPSHOT BEGIN TRAN SELECT * FROM TestTable WAITFOR DELAY '00:00:10' SELECT * FROM TestTable ROLLBACK یک صفحه New Query دیگر باز کنید و دستورات زیر را در آن کپی نمایید. INSERT INTO TestTable(Field1,Field2,Field3) VALUES (200,200,200) سخن پایانی Isolation Level در SQL Server، همانند مثالهای قبلی ابتدا دستورات اول را اجرا کرده و سپس سریع دستورات دوم را اجرا نمایید. همان طور که میبینید اجرای دستورات دوم منتظر اتمام تراکنش دستورات اول نخواهد ماند ولی جالب اینجاست که خروجی هر دو Select در دستورات اول دقیقا مشابه هم میباشد. مانند شکل زیر. ما در نیک آموز منتظر نظرات ارزشمند شما درباره این مقاله هستیم. چه رتبه ای میدهید؟ میانگین ۴.۱ / ۵. از مجموع ۲۵ اولین نفر باش دانلود مقاله آشنایی با Isolation Level در SQL Server فرمت PDF 9 صفحه حجم 1 مگابایت دانلود مقاله معرفی نویسنده مقالات 20 مقاله توسط این نویسنده محصولات 65 دوره توسط این نویسنده مسعود طاهری مسعود طاهری مدرس و مشاور ارشد SQL Server & BI ، مدیر فنی پروژههای هوش تجاری (بیمه سامان، اوقاف، جین وست، هلدینگ ماهان و...) ، مدرس دورههــای SQL Server و هوشتجاری در شرکت نیکآموز و نویسنده کتاب PolyBase در SQL Server معرفی محصول مسعود طاهری دوره ۳ در ۱ آموزش performance tuning در SQL Server 6.700.000 تومان 4.020.000 تومان مقالات مرتبط ۰۲ آبان SQL Server ابزار Database Engine Tuning Advisor؛ مزایا، کاربردها و روش استفاده تیم فنی نیک آموز ۱۵ مهر SQL Server معرفی Performance Monitor ابزار مانیتورینگ SQL Server تیم فنی نیک آموز ۱۱ مهر SQL Server راهنمای جامع مانیتورینگ بکاپ ها در SQL Server تیم فنی نیک آموز ۰۸ مهر SQL Server Resource Governor چیست؟ آشنایی با نحوه پیکربندی و اهمیت های آن تیم فنی نیک آموز دیدگاه کاربران لغو پاسخ دیدگاه نام و نام خانوادگی ایمیل ذخیره نام، ایمیل و وبسایت من در مرورگر برای زمانی که دوباره دیدگاهی مینویسم. موبایل برای اطلاع از پاسخ لطفاً مرا با خبر کن ثبت دیدگاه Δ علی ۱۰ / ۰۳ / ۹۶ - ۰۱:۵۰ سلام مطالب سایتتون رو دیدم. فوق العاده س توی سایتای فارسی. واقعا تبریک میگم که همچین سایت تخصصی و موفقی دارید. و یک سوال هم از خدمتتون دارم : دو تا جدول داریم مثلا فاکتور و ریزخرید(اینطور فرض کنید چون توضیح جداول اصلی خیلی زمان بره). با صدور فاکتور، به تعداد مشخص و با آیدی های متوالی، ریزخرید توی جدول خودش ایجاد میشه. میخوایم طوری باشه که این توالی حفظ بشه! فاکتور حاوی “تعداد، ابتدا و انتها” واسه ریزخریدهاش هست. واسه همین باید این توالی حفظ بشه. سوالی که از خدمتتون دارم اینه که چطور باید اینکار رو کرد؟ بیشتر دغدغه م روی همزمانی درخواستها به دیتابیس هست.(موقع اینزرت و البته احتمالا حذف. البته ریزخریدها ثابت هستن و حذف و اضافه شدنشون تابع خود فاکتور هست! یعنی تقریبا میشه گفت ثابت هستن به ازای یک فاکتور) از اونجایی که تخصص روی SQL ندارم، روش ابتدایی که به ذهنم رسیده بود، یک جدول اضافی با یک فیلد بیتی برای لاک کردن!!! بود که امیدوارم زیاد نخندید بهش! 🙂 پیشاپیش متشکر از راهنماییتون… پاسخ به دیدگاه فرید طاهری ۱۳ / ۰۳ / ۹۶ - ۰۷:۰۶ با سلام و تشکر از نظر شما. برای طراحی جدول فاکتور شما باید به روش زیر اقدام کنید: 1. یک جدول به عنوان Master باید داشته باشید که اطلاعات (ID مشتری، ID فاکتور، تاریخ فاکتور، مبلغ کل فاکتور، شماره فاکتور) داشته باشد. 2. یک جدول به عنوان Detail باید داشته باشید که اطلاعات ( ID , Detail ID فاکتور، ID کالا، تعداد کالا، مبلغ کالا، مبلغ کل هر سطر (تعداد * مبلغ کالا)) را داشته باشید. کلید اصلی در جدول Master عبارت است از ID فاکتور و کلید خارجی در جدول Detail عبارت است از ID فاکتور سعی کنید از TVP استفاده کنید تا مشکلات همزمانی و Lock را نداشته باشید. موفق باشید. ۱ پاسخ به دیدگاه علی ۰۸ / ۱۲ / ۹۵ - ۰۵:۳۰ خیلی عالی بود منون از شما پاسخ به دیدگاه ha_zarabi_vb6@outlook.com ۱۰ / ۰۱ / ۹۵ - ۱۱:۱۹ با سلام و خسته نباشید مطالب خیلی خوب توضیح داده شده بود از بابت این آموزش بسیار بسیار مفید خیلی مچکرم پاسخ به دیدگاه پیام ۰۶ / ۰۸ / ۹۴ - ۱۰:۴۸ سلام مهندسواقعا ممنونمن چند روزه دارم دنبال این مطالب میگردمهیچ جا این جو راحت و صریح توضیح ندادنواقعا مرسی پاسخ به دیدگاه MEHDI ۱۱ / ۰۷ / ۹۴ - ۰۱:۲۱ سلامضمن تشکر از مقاله خوبتون.مقاله ای هم در باب نرمال سازی داده ها در sql ارائه کنید پاسخ به دیدگاه سعید شکری ۲۳ / ۰۵ / ۹۴ - ۰۶:۲۵ سلاماین مبحث isolation level خیلی مبحث جالبیه و میتونه تا حدودی جلوی deadlock رو بگیره اگر ما یه جدول خیلی پرکاربرد داشته باشیم و isolation level رو روی حالت uncommited بزاریم مشکلی پیش میاد؟اگر phantom read اتفاق بیفته مشکلی داره؟ پاسخ به دیدگاه مسعود طاهری ۲۳ / ۰۵ / ۹۴ - ۰۸:۱۶ بله استفاده مناسب از Isolation Level می تواند جلوی Deadlock را بگیرد. در ضمن یادتون باشه از Isolation Level نوع Uncommitted استفاده کنید تمامی مشکلات همزمانی را خواهید داشت. فیلم مسابقه و جواب آن را نگاه کنید. در کوئری مربوط به آن از With (NoLock) استفاده کرده ایم عملکرد آن دقیقا مثل Isolation Level نوع Uncommitted می باشد. بهترین حالت برای پروژه ها ۱- ReadCommitted ۲-SnapShot (با توجه به اینکه از TempDB زیاد استفاده می شود. بهتر است که تنظیمات اصولی برای TempDB انجام شود.) به زودی یک دوره ۴ جلسه ای در زمینه افزایش سرعت کوئری ها برگزار خواهیم کرد. در این دوره این موارد را به خوبی بررسی خواهیم کرد. پاسخ به دیدگاه عاطفه حسن پور ۲۲ / ۰۳ / ۹۴ - ۰۱:۵۵ ممنون جناب طاهری اموزش خوبی بود پاسخ به دیدگاه علی یگانه مقدم ۳۰ / ۰۱ / ۹۴ - ۰۶:۰۰ ممنون آموزش خوبی بود و خیلی ساده بیانش کرده بودید و کاربرد عملی زیادی هم داره پاسخ به دیدگاه داوود طاهرخانی ۱۰ / ۰۱ / ۹۴ - ۰۴:۵۱ ممنون مهندس خیلی خیلی جامع و روشن بود پاسخ به دیدگاه مسعود طاهری ۲۳ / ۰۵ / ۹۴ - ۰۸:۱۶ بله استفاده مناسب از Isolation Level می تواند جلوی Deadlock را بگیرد. در ضمن یادتون باشه از Isolation Level نوع Uncommitted استفاده کنید تمامی مشکلات همزمانی را خواهید داشت. فیلم مسابقه و جواب آن را نگاه کنید. در کوئری مربوط به آن از With (NoLock) استفاده کرده ایم عملکرد آن دقیقا مثل Isolation Level نوع Uncommitted می باشد. بهترین حالت برای پروژه ها ۱- ReadCommitted ۲-SnapShot (با توجه به اینکه از TempDB زیاد استفاده می شود. بهتر است که تنظیمات اصولی برای TempDB انجام شود.) به زودی یک دوره ۴ جلسه ای در زمینه افزایش سرعت کوئری ها برگزار خواهیم کرد. در این دوره این موارد را به خوبی بررسی خواهیم کرد. پاسخ به دیدگاه 1 2