چنانچه در بخش اول از این مقاله توضیح داده شد، برنامههای مبتنی بر SQL Server با استفاده از قابلیت FILESTREAM امکان ذخیره دادههای بدونساختار، همچون اسناد و تصاویر، بر روی فایل سیستم امکان پذیر میگردند. برنامهها میتوانند از APIهای Streaming مناسب و عملکرد فایل سیستم نهایت استفاده را برده و در آنِ واحد هماهنگی تراکنشی را میان دادههای بدونساختار و دادههای ساختاریافته مربوطه حفظ نمایند. علاوه بر آن در این مجموعه مقالات به شرح ویژگیهای FILESTREAM، طریقهی عملکرد آن، بهترین زمان استفاده، نحوهی استفاده از ذخیرهساز آن و همچنین مزایای آن همچون مدیریت و امنیت یکپارچه و منسجم پرداخته شد. در این بخش نیز به طریقهی دسترسی به دادههای BLOB از طریق Transact-SQL و دسترسیStreaming فایل سیستم، تداومپذیری تراکنشی FILESTREAM، مفاهیم ایزولهسازی، APIهای فایل سیستم و سطوح ایزولهسازی تحت پشتیبانی پرداخته میشود.
دسترسی به دادههای BLOB با استفاده از Transact-SQL و دسترسیFile System Streaming
بعد از ذخیرهی دادهها در یک ستون FILESTREAM، میتوان یا با استفاده از تراکنشهای Transact-SQL و یا با استفاده از APIهای Win32، به فایلها دسترسی پیدا کرد.
دسترسی با استفاده از Transact-SQL
با استفاده از Transact-SQL میتوان دادههای FILESTREAM را وارد کرد، بروزرسانی و یا حذف نمود.
- میتوان عملیاتی را وارد کرد تا فیلد FILESTREAM را با مقدار Null یا مقدار تهی و یا دادهی Inline نسبتاً کوتاهی Prepopulate نمود. با اینحال مقدار زیادی داده در یک فایل که از رابطهای کاربری Win32 استفاده میکند، بهینهتر Stream میشود.
- هنگام بروزرسانی یک فیلد FILESTREAM، دادهی BLOB اصلی در فایل سیستم اصلاح میشود. هنگامیکه یک فیلد FILESTREAM بر روی NULL تنظیم شود، دادهی BLOBی که با آن فیلد مرتبط باشد پاک خواهد شد. نمیتوان از بروزرسانی Chunked مختص به Transact-SQL که به شکل WRITE() پیادهسازی میشود، برای اعمال بروزرسانی جزئی بر روی دادهها استفاده نمود.
- هنگامیکه کاربر یکی از ردیفها را حذف کرده و یا جدولی که حاوی دادههای FILESTREAM است را Truncate میکند، دادهی BLOB زیرین موجود در فایل سیستم را نیز حذف میکند.
دسترسی به فایل سیستم Streaming
پشتیبانی از Win32 Streaming در بافت یک تراکنش SQL Server عمل میکند. میتوان درون یک تراکنش از عملکردهای FILESTREAM استفاده نمود تا یک مسیر منطقی فایل سیستم UNC مختص به یک فایل بهدست آید. سپس باید از OpenSQLFilestream API برای بدست آوردن یک کنترل فایل (File Handle) استفاده نمود. سپس میتوان از این Handle توسط رابطهای کاربری Streaming مختص به Win32 همچون ()ReadFile و ()WriteFile برای دسترسی به فایل و بروزرسانی آن از طریق فایل سیستم اقدام کرد. از آنجایی که عملیاتهای فایل، تراکنشی هستند، نمیتوان از طریق فایل سیستم، فایلهای FILESTREAM را حذف و یا تغییر نام داد.
مدل اجرایی دستورات
دسترسی فایل سیستم FILESTREAM با استفاده از File Open و File Close، از یک دستور مختص به Transact-SQL پیروی میکند. دستور مربوطه هنگامی آغاز میشود که یک File Handle باز گردد و هنگامی پایان مییابد که Handle بسته شود.
Storage Namespace
در FILESTREAM، کنترل Namespace سیستمفایل فیزیکی BLOB در اختیار Database Engine قرار دارد. یک تابع Intrinsic تازه با نام PathName، مسیر منطقی UNC مختص به BLOB را ارائه میدهد که به هر سلول FILESTREAM موجود در جدول مرتبط است. برنامهی کاربردی از این مسیر منطقی استفاده میکند تا Win32 Handle را بهدست آورد و با استفاده از رابطهای کاربری عادی فایل سیستم Win32 بر روی دادههای BLOB کار کند. اگر مقدار ستون FILESTREAM بر روی NULL باشد، این تابع نیز به صورت NULL باز خواهد گشت.
دسترسی فایل سیستم Transact شده
تابعIntrinsic جدیدی با نام ()GET FILESTREAM TRANSACTION CONTEXT که Tokenی را ارائه میدهد و نشاندهندهی تراکنشی است که Session در حال حاضر با آن مرتبط است. تراکنش باید آغاز شده باشد و هنوز لغو نشده و انجام نپذیرفته باشد. با بهدست آوردن یک Token، برنامهی کاربردی عملیاتهای Streaming فایل سیستم FILESTREAM را به یک تراکنش آغازشده پیوند میزند. این تابع در صورتی که هیچ تراکنشی بهوضوح آغاز نشده باشد، NULL باز خواهد گشت.
تمام File Handleها باید پیش از آنکه تراکنش انجام پذیرفته یا لغو شود، بسته شوند. اگر یک Handle خارج از حیطهی تراکنش باز بماند، Readهای اضافی بر روی Handle مسبب بروز خرابی خواهند شد. Writeهای اضافی بر روی Handle با موفقیت انجام خواهند پذیرفت، ولی دادههای حقیقی بر روی دیسک Write نخواهند شد. به همین صورت، اگر دیتابیس یا Instance مختص به Database Engine خاموش شود، تمام Handleهای باز بیاعتبار میگردند.
تداومپذیری تراکنشی
با FILESTREAM هنگام انجام پذیرفتنِ تراکنش، Database Engine از تداومپذیری تراکنشی برای دادهی FILESTREAM BLOB که از دسترسی Streaming فایل سیستم اصلاح شده است، اطمینان حاصل مینماید.
مفاهیم ایزولهسازی
مفاهیم ایزولهسازی (Isolation Semantics) توسط سطوح ایزولهسازی تراکنش Database Engine کنترل و مدیریت میشوند. از سطح ایزولهسازی Read-Committed برای Transact-SQL و دسترسی فایل سیستم پشتیبانی میشود. از عملیاتهای Read قابل تکرار و همچنین ایزولهسازیهای Serializable و Snapshot نیز پشتیبانی میگردد. اما Dirty Read تحت پشتیبانی نیست.
عملیاتهای باز دسترسی فایل سیستم منتظر هیچ Lockی نمیمانند. در عوض، فعالیتهای باز اگر بهدلیل ایزولهسازی تراکنش نتوانند به داده دسترسی پیدا کنند، بلافاصله Fail خواهند شد. اگر عملیات باز بهدلیل نقض ایزولهسازی (Isolation Violation) نتواند ادامه یابد، اعلانهای API درحال Stream با پیام ERROR_SHARING_VIOLATION ناموفق خواهند ماند.
برای اینکه بتوان بروزرسانیهای جزئی انجام داد، برنامهی کاربردی میتواند یک تجهیز کنترل FS (FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT) صادر کند تا محتوای قدیمی را وارد فایلی کند که Handle بازشده به آن ارجاع میدهد. این عمل منجر به ایجاد یک کپی از محتوای قدیمی Server-Side خواهد شد. در جهت عملکرد بهتر برنامهی کاربردی و جلوگیری از برخورد با Time-outهای احتمالی، توصیه میشود که کاربران هنگام کار با فایلهای بسیار حجیم از Asynchronous I/O استفاده نمایند.
اگر FSCTL بعد اینکه بر روی Handle عمل Write انجام شد صادر شود، آخرین عملیات Write باقی خواهد ماند و Writeهای پیشین که بر روی Handle انجام شده بودند، از دست خواهند رفت.
APIهای فایل سیستم و سطوح ایزولهسازی تحت پشتیبانی
هنگامیکه یک API فایل سیستم نتواند یک فایل را بهدلیل نقض ایزولهسازی باز کند، یک استثنای ERROR_SHARING_VIOLATION بازگشت داده میشود. این نقض ایزولهسازی هنگامی رخ میدهد که دو تراکنش سعی داشته باشند به یک فایل واحد دسترسی پیدا کنند. نتیجهی عملیات دسترسی به حالت بازشدنِ فایل و نسخهی SQL Serverی که تراکنش بر روی آن در حال انجام است بستگی دارد. جدول ذیل نتایج احتمالی دو تراکنش که سعی دارند به یک فایل دسترسی پیدا کنند را به نمایش میگذارد:
نتیجه بر روی SQL Server 2008v2 و نسخههای بعد | نتیجه بر روی SQL Server 2008 | تراکنش 2 | تراکنش 1 |
هر دو با موفقیت انجام میپذیرند | هر دو با موفقیت انجام میپذیرند | با دسترسی Read | با دسترسی Read |
هردو با موفقیت انجام میپذیرند. عملیاتهای Write تحت تراکنش شماره 2 بر روی عملیاتهای Read انجام پذیرفته در تراکنش شماره 1 تأثیر نمیگذارند. | هردو با موفقیت انجام میپذیرند. عملیاتهای Write تحت تراکنش شماره 2 بر روی عملیاتهای Read انجام پذیرفته در تراکنش شماره 1 تأثیر نمیگذارند. | با دسترسی Write | با دسترسی Read |
هر دو با موفقیت انجام میپذیرند | عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | با دسترسی Read | با دسترسی Write |
عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | با دسترسی Write | با دسترسی Write |
هر دو با موفقیت انجام میپذیرند | هر دو با موفقیت انجام میپذیرند | با دسترسی SELECT | با دسترسی Read |
هردو با موفقیت انجام میپذیرند. عملیاتهای Write تحت تراکنش شماره 2 بر روی عملیاتهای Read انجام پذیرفته در تراکنش شماره 1 تأثیر نمیگذارند. | هردو با موفقیت انجام میپذیرند. عملیاتهای Write تحت تراکنش شماره 2 بر روی عملیاتهای Read انجام پذیرفته در تراکنش شماره 1 تأثیر نمیگذارند. | با دسترسی UPDATE و DELETE | با دسترسی Read |
هر دو با موفقیت انجام میپذیرند | تراکنش شماره 2 بلاک میشود تا وقتیکه تراکنش شماره 1 یا با موفقیت انجام پذیرد، یا تراکنش را پایان دهد و یا مدت زمان قفل تراکنش تمام شود. | با دسترسی SELECT | با دسترسی Write |
تراکنش شماره 2 بلاک میشود تا وقتیکه تراکنش شماره 1 یا با موفقیت انجام پذیرد، یا تراکنش را پایان دهد و یا مدت زمان قفل تراکنش تمام شود. | تراکنش شماره 2 بلاک میشود تا وقتیکه تراکنش شماره 1 یا با موفقیت انجام پذیرد، یا تراکنش را پایان دهد و یا مدت زمان قفل تراکنش تمام شود. | با دسترسی UPDATE و DELETE | با دسترسی Write |
هر دو با موفقیت انجام میپذیرند | هر دو با موفقیت انجام میپذیرند | با دسترسی Read | با دسترسی SELECT |
هردو با موفقیت انجام میپذیرند. عملیاتهای Write تحت تراکنش شماره 2 بر تراکنش شماره 1 تأثیر نمیگذارند. | هردو با موفقیت انجام میپذیرند. عملیاتهای Write تحت تراکنش شماره 2 بر تراکنش شماره 1 تأثیر نمیگذارند. | با دسترسی Write | با دسترسی SELECT |
هر دو با موفقیت انجام میپذیرند | عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | با دسترسی Read | با دسترسی UPDATE و DELETE |
عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | با دسترسی Write | با دسترسی UPDATE و DELETE |
هر دو با موفقیت انجام میپذیرند | هر دو با موفقیت انجام میپذیرند | با دسترسی Read | با دسترسی Select همراه با Read قابل تکرار |
عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | عملیات باز بر روی تراکنش شماره 2 با یک استثنای ERROR_SHARING_VIOLATION ناموفق خواهد ماند. | با دسترسی Write | با دسترسی Select همراه با Read قابل تکرار |
ــــــــــــــــــــــــــــــــــــــ
آشنایی با FILESTREAM در SQL Server – قسمت اول
آشنایی با FILESTREAM در SQL Server – قسمت دوم (پایانی)