افزايش كارآئی برنامه های وب در ASP.NET 2.0 ( بخش دوم )

پس از فعال كردن پتانسيل caching در كنترل SqlDataSource ، ماحصل اجرای SelectQuery برای استفاده آتی Cache می گردد . در صورت اجراء يك select query پارامتريك ، كنترل فوق برای هر مجموعه از مقادير پارامترها يك نسخه جداگانه را cache می نمايد . مثلا" ‌فرض كنيد قصد داريم صفحه ای را ايجاد نمائيم كه در آن ليست كاركنان بر اساس نام شهر نمايش داده شود . پس از انتخاب شهر توسط كاربر ، از يك كنترل
دوشنبه، 7 بهمن 1387
تخمین زمان مطالعه:
موارد بیشتر برای شما
افزايش كارآئی برنامه های وب در ASP.NET 2.0 ( بخش دوم )
افزايش كارآئی برنامه های وب در ASP.NET 2.0  ( بخش دوم )
افزايش كارآئی برنامه های وب در ASP.NET 2.0 ( بخش دوم )

Caching در كنترل منبع داده SqlDataSource

پس از فعال كردن پتانسيل caching در كنترل SqlDataSource ، ماحصل اجرای SelectQuery برای استفاده آتی Cache می گردد . در صورت اجراء يك select query پارامتريك ، كنترل فوق برای هر مجموعه از مقادير پارامترها يك نسخه جداگانه را cache می نمايد .
مثلا" ‌فرض كنيد قصد داريم صفحه ای را ايجاد نمائيم كه در آن ليست كاركنان بر اساس نام شهر نمايش داده شود . پس از انتخاب شهر توسط كاربر ، از يك كنترل SqlDataSource برای برگرداندن ركوردهای كاركنانی كه با نام شهر مطابقت می نمايند جهت نمايش در يك grid استفاده شده است .
كد زير نحوه استفاده از كنترل SqlDataSource با هدف فعال كردن caching را نشان می دهد .

<asp:SqlDataSource ID="sourceEmployees" runat="server"
      ProviderName="System.Data.SqlClient"
      EnableCaching="True"CacheDuration="600"
      ConnectionString="<%$ ConnectionStrings:Northwind %>"
      SelectCommand="SELECT EmployeeID, FirstName, LastName, Title, City FROM Employees WHERE City=@City">
     <SelectParameters>
          <asp:ControlParameter ControlID="lstCities" Name="City" PropertyName="SelectedValue" />
     </SelectParameters>
</asp:SqlDataSource>

در مثال فوق ، پس از انتخاب شهر توسط كاربر ، يك query جداگانه اجراء خواهد شد تا ليست كاركنان با توجه به شهر انتخاب شده ، بازيابی و در يك DataSet به ميزان 10 دقيقه ( 600 ثانيه ) ، cache گردد . در صورت انتخاب يك شهر ديگر توسط كاربر ، پردازش فوق تكرار و مجددا" يك DataSet جديد ايجاد و cache می گردد. در صورت انتخاب يك شهر توسط كاربری كه قبلا" توسط كاربران ديگر انتخاب شده است ، DataSet مورد نظر از cache بازيابی خواهد شد ( مشروط به عدم اتمام مدت زمان اعتبار حضور آن در cache ) .
توجه داشته باشيد زمانی كه مقدار خصلت DataSourceMode معادل DataSet در نظر گرفته شده باشد (مقدار پيش فرض) ، پتانسيل caching در كنترل منبع داده SqlDataSource به خوبی كار می كند . شی DataReader نمی تواند بطور موثر cache گردد چراكه شی فوق قادر به برقراری يك ارتباط مستقيم و زنده با بانك اطلاعاتی نمی باشد .
در صورتی كه برخی پارامترها نسبت به پارامترهای ديگر با فركانس بيشتری استفاده شده باشند ، caching جداگانه نتايج با توجه به مقادير مختلف پارامترها وضعيت مطلوبتری را به دنبال خواهد داشت . مثلا" اگر نتايج مربوط به شهر "X " بمراتب بيش از نتايج شهر "Y" درخواست گردد ، اين اطمينان ايجاد خواهد شد كه نتايج شهر "X" بمراتب بيش تر در cache باقی خواهند ماند حتی اگر DataSet مربوط به شهر "Y" از حافظه خارج شده باشد .
به عبارت ديگر ، در صورتی كه مقادير پارامتر ها جملگی با فركانس مشابهی استفاده شوند ، روش فوق يك راه حل مناسب نمی باشد . يكی از مسائل مرتبط با راه حل فوق ، زمانی است كه مدت زمان حضور آيتم های cache شده به اتمام رسيده باشد و لازم است كه جندين query را بر روی بانك اجراء نمود تا نسخه های جداگانه ای از cache را ايجاد نمايد ( نسخه های cache جداگانه با توجه به مقدار پارامتر ) . قطعا" روش فوق دارای كارآئی بمراتب كمتری نسبت به حالتی است كه تمامی نتايج صرفا" با يك query بازيابی می گردد .
در چنين مواردی می توان تمامی ركوردهای كاركنان را بازيابی و در cache ذخيره نمود . در ادامه ، كنترل SqlDataSource می تواند صرفا" ركوردهای مورد نياز را متناسب با درخواست كاربر از DataSet بازيابی نمايد . بدين ترتيب ، يك DataSet به همراه تمامی ركوردهای cache شده می تواند صرفنظر از مقدار پارامتر دريافتی پاسخگو باشد .
برای نيل به خواسته فوق ، می بايست دو تغيير اساسی را در كد فوق اعمال نمود .
اولين تغيير : بازيابی تمامی ركوردها با استفاده از select query ( عدم استفاده از SelectParameter ) . كد زير نحوه انجام اين كار را نشان می دهد :

<asp:SqlDataSource ID="sourceEmployees" runat="server"
   SelectCommand="SELECT EmployeeID, FirstName, LastName, Title, City FROM Employees"
    ...>
</asp:SqlDataSource>

دومين تغيير :تعريف يك عبارت فيلترينگ . بدين منظور از بخش WHERE در query با اندك تفاوت هائی استفاده می گردد . در صورت دريافت مقدار فيلتر مورد نظر از يك منبع ديگر ( نظير يك كنترل ) ، می بايست از يك و يا چندين placeholder استفاده نمود . بدين منظور از گرامر {0} برای اولين پارامتر و {1} برای دومين پارامتر و ... استفاده می گردد . در ادامه امكان استفاده از مقدار مختلف فيلترها كه توسط بخش <FilterParameters> مشخص شده است ، فراهم می گردد .
كد زير نحوه تعريف كنترل منبع داده SqlDataSource را پس از اعمال دو تغيير فوق نشان می دهد .

<asp:SqlDataSource ID="sourceEmployees" runat="server"
      ProviderName="System.Data.SqlClient"
      EnableCaching="True" CacheDuration="600"
      ConnectionString="<%$ ConnectionStrings:Northwind %>"
     SelectCommand="SELECT EmployeeID, FirstName, LastName, Title, City FROM Employees"
       FilterExpression="City='{0}'"
       EnableCaching="True">
      <FilterParameters>
         <asp:ControlParameter ControlID="lstCities" Name="City" PropertyName="SelectedValue" />
      </FilterParameters>

توجه داشته باشيد در صورت عدم استفاده از caching ، ضرورتی به فعال كردن فيلترينگ وجود ندارد . چراكه در صورت استفاده از فيلترينگ بدون caching ، در واقع تمامی result set بازيابی خواهد شد تا در ادامه بتوان بخشی از ركوردهای آن را بازيابی كرد . بدين ترتيب ، پس از هر postback و بدون توجيه منطقی تمامی ركوردها ( بيش از آن چيزی كه مورد نياز است ) ، بازيابی می گردد .

caching در كنترل ObjectDataSource

caching كنترل ObjectDataSource با اشياء داده برگردانده شده توسط SelectMethod به خوبی كار می كند . در صورت استفاده از يك query پارامتريك ،‌ كنترل ObjectDataSource درخواست هائی با پارامترهای مختلف را بطور جداگانه cache می نمايد.
caching كنترل ObjectDataSource دارای يك محدوديت قابل ملاحظه است و صرفا" زمانی كار می كند كه SelectMethod آن يك DataSet يا DataTable را برمی گرداند . در صورت برگرداندن هر نوع اشياء داده ديگر ، با يك NotSupportedException مواجه خواهيم شد .
برای غلبه بر محدوديت فوق می توان پياده سازی data caching را درون متد مربوطه انجام و اقدام به درج دستی اشياء درون data cache كرد. در واقع ، caching درون متد مورد نظر می تواند كارآئی بمراتب بهتری را نيز به دنبال داشته باشد چراكه امكان به اشتراك گذاشتن اشياء cache شده مشابه بين چندين متد فراهم می گردد . مثلا" می توان يك DataTable حاوی ليستی از محصولات را cache و در ادامه از آيتم های cache شده در متدهای GetProductCategories و GetProductsByCategory استفاده نمود .

Caching با وابستگی

ماهيت منابع داده نظير يك بانك اطلاعاتی بگونه ای است كه به مرور زمان اطلاعات درون آنها تغيير می يابد . در صورتی كه در يك برنامه از caching استفاده می گردد ، همواره اين احتمال وجود خواهد داشت كه اطلاعات موجود در cache متاثر از اين تغييرات نباشد و داده بهنگام نشده از cache استخراج و در اختيار كاربران گذاشته شود.
برای كمك در جهت حل اين نوع مشكلات ، ASP.NET از caching با وابستگی حمايت می نمايد . با استفاده از ويژگی فوق اين امكان در اختيار پياده كنندگان قرار می گيرد تا بتوانند حضور يك آيتم در cache را به منابع ديگری وابسته نمايند . در چنين مواردی ، زمانی كه در منبع مورد نظر تغييراتی ايجاد گرديد ، آيتم cache شده بطور اتوماتيك از cache خارج می گردد .
ASP.NET از سه نوع وابستگی حمايت می نمايد :
• وابستگی با ساير آيتم های Cache شده
• وابستگی با فايل ها و يا فولدرها
• وابستگی با يك query بانك اطلاعاتی
برای ايجاد يك cache وابسته ، می بايست يك شی CacheDependency ايجاد و در ادامه از آن در زمان اضافه كردن آيتم مورد نظر به cache استفاده كرد .
كد زير يك آيتم cache شده را ايجاد كه بطور اتوماتيك و پس از ايجاد تغييرات در فايل xml از cache خارج می شود .

ايجاد يك وابستگی برای فايل ProductList.xml

 Dim prodDependency As New CacheDependency(Server.MapPath("ProductList.xml"))

در زمان درج آيتم مورد نظر در cache از شی CacheDependency ايجاد شده در مرحله قبل استفاده می گردد .
ا

اضافه كردن يك آيتم در cacheكه حضور آن در cacheبه فايل  ProductList.xml  وابسته می گردد

 Cache.Insert("ProductInfo", prodInfo, prodDependency)

پس از ايجاد شی CacheDependency ، مانيتورينگ آغاز می گردد . در صورتی كه فايل xml قبل از افزودن آيتم وابسته به درون cache تغيير يافته باشد ، بلافاصله تاريخ اعتبار آيتم موردنظر پس از افزودن به cache به پايان می رسد .
شی CacheDependency چندين constructor را ارائه می نمايد . در مثال قبل مشاهده گرديد كه چگونه شی فوق قادر به ايجاد يك وابستگی بر اساس يك فايل است كه نام آن به عنوان constructor در نظر گرفته می شود . همچنين می توان يك دايركتوری را معرفی تا تغييرات آن مانيتور گردد .
مثال : ايجاد و درج يك آيتم درون cache كه حضور آن در cache به يك فايل وابسته می گردد
در اين مثال با ايجاد يك شی وابسته ( يك فايل text ) ،‌ يك عبارت ( " آيتم cache شده وابسته " ) وابسته به شی فوق را در cache قرار می دهيم . تا زمانی كه داده موجود در فايل text تغيير نيابد ، آيتم مورد نظر در cache باقی می ماند و می توان از آن استفاده كرد . در صورت تغيير در شی وابسته ( فايل dependency.txt ) اعتبار آيتم cache شده به اتمام رسيده و بطور اتوماتيك از cache خارج می شود .
در اين برنامه از دو button به نام " تغيير فايل " و " بررسی آيتم cache شده " استفاده شده است . با استفاده از دكمه "بررسی آيتم cache شده " ، حضور آيتم مورد نظر در cache بررسی و پيام مناسب در خروجی نمايش داده می شود . در صورت كليك بر روی دكمه "تغيير فايل " ، محتويات شی وابسته ( فايل dependency.txt ) تغيير يافته و آيتم مورد نظر از cache خارج می گردد .
كد برنامه فوق در جدول زير نشان داده شده است .

درج يك آيتم  در cache  با وابستگی به يك شی ( فايل )

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<%@ Import Namespace="System.IO" %>

<script runat="server">
'=====================================================================
Sub cmdModify_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdModify.Click
  lblInfo.Text &= "تغيير فايلوابسته<br />"
  Dim w As StreamWriter = File.CreateText(Server.MapPath("dependency.txt"))
  w.Write(DateTime.Now)
  w.Flush()
  w.Close()
End Sub
'=====================================================================
 Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 If Not Me.IsPostBack Then
    lblInfo.Text &= "ايجاد آيتم وابسته<br />"
    Cache.Remove("File")
    Dim dependency As New System.Web.Caching.CacheDependency( _
    Server.MapPath("dependency.txt"))
    Dim item As String = "آيتمcache شده وابسته"
    lblInfo.Text &= "اضافه كردن آيتم وابسته<br />"
    Cache.Insert("File", item, dependency)
 End If
End Sub
'=====================================================================
Sub cmdGetItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdGetItem.Click
  If Cache("File") Is Nothing Then
      lblInfo.Text &= " آيتم مورد نظر در‌‍cache موجود نمی باشد و امكان بازيابی آن وجود ندارد<br />"
    Else
     Dim cacheInfo As String = CType(Cache("File"), String)
      lblInfo.Text &= " آيتم موردنظر در‌‍cache موجود است و امكان بازيابی آن وجود دارد<br />"
  End If
 End Sub
'=====================================================================
</script>

<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl">
 <head id="Head1" runat="server">
  <title>تستcaching </title>
 </head>
 <body style="font-family: Tahoma">
   <form id="Form1" method="post" runat="server">
    <asp:button id="cmdModify" runat="server" Text="تغيير فايل" Width="103px"
                       Font-Names="Tahoma"></asp:button>
    <asp:button id="cmdGetItem" runat="server" Text="بررسی آيتمcache شده" Width="140px"
                      Height="24px" Font-Names="Tahoma"></asp:button><br /><br />
     <asp:label id="lblInfo" runat="server" Width="480px" Height="192px" BorderWidth="2px"
                     BorderStyle="Groove" Font-Names="Tahoma" Font-Size="Small"
                     BackColor="LightYellow"></asp:label>
  </form>
 </body>
</html>

توضيحات :

• در زمان فراخوانی برنامه فوق از طريق روتين Page_laod عمليات زير انجام می شود :
- ايجاد يك شی dependency ( يك فايل متن با نام dependency.txt )
- درج آيتم مورد نظر با نام File و مقدار " آيتم cache شده وابسته " در cache
- نمايش پيام های مناسب در خروجی به كمك كنترل سرويس دهنده label ( با نام lblInfo )
• روتين cmdGetItem_Click ، وجود آيتم مورد نظر را در Cache بررسی و در صورتی كه اين آيتم در cache موجود نباشد يك پيام خاص از طريق كنترل سرويس دهنده label در خروجی نمايش داده می شود . در صورت وجود آيتم مورد نظر در cache ، مقدار آن از cache بازيابی و يك پيام خاص از طريق كنترل سرويس دهنده label در خروجی نمايش داده می شود .
• روتين cmdModify_Click ، مسئوليت ايجاد تغيير در فايل وابسته ( نام dependency.txt ) را برعهده دارد . در روتين فوق پس از ايجاد فايل ، تاريخ جاری سيستم در آن نوشته می گردد .
SQL Server cache dependency ، يكی از نوع های پيچيده caching وابسته است كه در ASP.NET 2.0 ارائه شده است . با استفاده از ويژگی فوق بطور اتوماتيك يك شی داده cache شده ( نظير يك DataSet ) پس از تغيير داده مرتبط در بانك اطلاعاتی ، غير معتبر می گردد . از پتانسيل فوق در در SQL Server 2005 ( شامل Express Edition ) و SQL Server 2000 حمايت می گردد .
سيستم آگاه سازی caching در SQL Server 2000 و SQL Server 7
ASP. NET از مدل pooling برای SQL Server 2000 و SQL Server 7 استفاده می نمايد . نسخه های قديمی تر SQL Server و ساير بانك های اطلاعاتی از ويژگی فوق حمايت نمی نمايند .
در اين روش ، ASP.NET يك ارتباط باز با بانك اطلاعاتی را نگاه داشته و به صورت دوره ای بروز هر گونه تغيير در يك جدول را بررسی می نمايد . نگهداری‌ يك اتصال باز به منزله بروز يك فاجعه در سطح بانك اطلاعاتی نمی باشد و صرفا" كار اضافه تری در سطح بانك اطلاعاتی ايجاد می گردد كه انجام آن فرآيند مختص به خود را دارد.
به منظور بهره گيری بيشتر و موثر از مدل pooling ، می بايست فرآيند pooling سريع تر و سبك تر از query اوليه ای باشد كه مسئوليت استخراج داده از بانك اطلاعاتی را برعهده دارد .
هدف سيستم آگاه سازی caching ، تشخيص به موقع انجام تغييرات در جداول يك بانك اطلاعاتی و غيرمعتبر كردن داده cache شده مرتبط با هر يك از جداول است .
برای فعال كردن سيستم آگاه سازی در SQL Server 2000 می بايست مراحل زير را دنبال نمود :‌
• مرحله اول : مشخص كردن جداولی از بانك اطلاعاتی كه نيازمند حمايت از سيستم آگاه سازی caching می باشند .
• مرحله دوم : فعال كردن سيستم آگاه سازی caching بر روی بانك اطلاعاتی مورد نظر به كمك برنامه خط دستوری aspnet_regsql.exe
• مرحله سوم : ريجستر كردن جداولی كه نيازمند حمايت از سيستم آگاه سازی caching می باشد . بدين منظور مجددا" از برنامه خط دستوری aspnet_regsql.exe و اين مرتبه در سطح جدول استفاده می گردد .
• مرحله چهارم : فعال كردن polling از طريق فايل web.config
پس از انجام مراحل چهارگانه فوق می توان اشياء SqlCacheDependency را ايجاد نمود .
در ادامه هر يك از مراحل فوق را با جزئيات بيشتری بررسی می نمائيم . مرحله اول : مشخص كردن جداولی از بانك اطلاعاتی كه نيازمند حمايت از سيستم آگاه سازی caching می باشند .
بدين منظور لازم است كه در اولين اقدام بانك اطلاعاتی و جداولی كه لازم است بر روی آنها سيستم آگاه سازی caching فعال شود ، شناسائی و انتخاب گردند . انتخاب بانك طلاعاتی و جداول مربوطه به رفتار يك برنامه و انتظارات از آن بستگی دارد كه می بايست توسط طراحان و پياده كنندگان برنامه های وب به دقت انجام شود .
مرحله دوم : فعال كردن سيستم آگاه سازی caching بر روی بانك اطلاعاتی مورد نظر به كمك برنامه خط دستوری aspnet_regsql.exe
قبل از اين كه بتوان از سيستم غيرمعتبر سازی Cache در SQL Server استفاده نمود ، می بايست سيستم آگاه سازی caching را برای بانك اطلاعاتی مورد نظر فعال كرد . به منظور انجام اين كار از برنامه خط دستوری aspnet_regsql.exe كه در مسير [ c:\[WinDir]\Microsoft.NET\Framework\[Version موجود است ، استفاده می گردد . برنامه فوق يك ابزار مديريتی برای فعال كردن و غيرفعال كردن ويژگی های ASP.NET بر روی يك سرويس دهنده SQL است . اين برنامه دارای سوئيچ های متعددی‌ است . ed ، يكی از سوئيچ های اين دستور است كه از آن برای فعال كردن SQL cache dependency بر روی يك بانك اطلاعاتی استفاده می گردد . همچنين ، از سوئيچ E به منظور مشخص كردن روش تائيد بر اساس يك اتصال ايمن و از سوئيچ d برای مشخص كردن بانك اطلاعاتی كه قرار است سيستم آگاه سازی caching بر روی آن فعال گردد ، استفاده می شود .
دستور زير نحوه استفاده از برنامه aspnet_regsql.exe به منظور فعال كردن سيستم آگاه سازی caching بر روی بانك اطلاعاتی AspNet استاندارد موجود بر روی سرويس دهنده جاری را نشان می دهد .

  aspnet_regsql -ed -E -d AspNet

پس از انجام عمليات فوق ، يك جدول جديد با نام SqlCacheTablesForChangeNotification به بانك اطلاعاتی با نام AspNet اضافه می گردد. جدول فوق دارای سه ستون notificationCreated ، tableName و changeId است و از آن برای پيگيری انجام تغييرات استفاده می گردد .
سرويس polling در ASP.NET با جدول فوق تعامل برقرار و از آن به منظور ارائه خدمات خود استفاده می نمايد . سيستم فوق و نحوه پياده سازی آن مزايای متعددی را به دنبال دارد :
• با توجه به اين كه جدول آگاه سازی تغييرات بمراتب كوچكتر از جدول حاوی داده cache شده است ، سرعت اجرای query بر روی آن سريعتر خواهد بود .
• با توجه به عدم استفاده از جدول آگاه سازی برای فعاليت های ديگر ، در زمان خواندن ركوردهای آن با مسائلی همچون قفل كردن ركوردها و همزمانی مواجه نخواهيم شد .
• باتوجه به اين كه چندين جدول در يك بانك اطلاعاتی مشابه از يك جدول آگاه سازی مشابه استفاده می نمايند ، می توان چندين جدول را بدون افزايش هزينه های بالاسری pooling در يك لحظه مانيتور كرد.
مرحله سوم : ريجستر كردن جداولی كه نيازمند حمايت از سيستم آگاه سازی caching می باشد.
پس از ايجاد جدول SqlCacheTablesForChangeNotification ، می بايست برای هر جدول موجود در بانك اطلاعاتی سيستم آگاه سازی caching فعال گردد . بدين منظور می توان از SqlCacheRegisterTableStoredProcedure و يا برنامه كاربردی aspnet_regsql به همراه پارامتر های et - ( فعال كردن سيستم آگاه سازی بر روی يك جدول ) و t - ( نام جدول ) استفاده نمود .
دستور زير نحوه فعال كردن سيستم آگاه سازی را برای جدول Employees بانك اطلاعاتی Northwind نشان می دهد .

  aspnet_regsql -et -E -d Northwind -t Employees

> پس از اجرای دستور فوق ، trigger آگاه سازی caching برای جدول Employees ايجاد می گردد .
مرحله چهارم : فعال كردن polling از طريق فايل web.config
در اين مرحله به ASP.NET اعلام می گردد كه از polling بانك اطلاعاتی استفاده نمايد .
برای فعال كردن سرويس polling از عنصر <sqlCacheDepency> در فايل web.config استفاده می گردد . بدين منظور لازم است كه خصلت enabled مقدار true را داشته باشد تا ويژگی فوق فعال گردد . همچنين توسط خصلت pollTime مدت زمان مورد نظر ( بر حسب ميلی ثانيه ) بين هر poll مشخص می گردد . هر اندازه مقدار خصلت فوق بيشتر باشد ، تغييرات با تاخير بيشتری تشخيص داده می شوند. در بخش <sqlCacheDepency> فايل web.config و به كمك <databases> بانك و يا بانك های اطلاعاتی مشمول سيستم آگاه سازی caching معرفی می گردند .
كد زير نحوه فعال كردن polling از طريق فايل web.config برای بانك اطلاعاتی Northwind را نشان می دهد .

فعال كردن pollingاز طريق فايل web.config

<configuration>
  <connectionStrings>
     <add name="Northwind" connectionString=
            "Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI"/>
     </connectionStrings>
 <system.web>
<caching>
  <sqlCacheDependency enabled="true" pollTime="15000" >
    <databases>
         <add name="Northwind" connectionStringName="Northwind" />
   </databases>
</sqlCacheDependency>

</caching>
...
</system.web>
</configuration>

نحوه كار سيستم آگاه سازی caching

پس از انجام مراحل اشاره شده بستر لازم برای استفاده از سيستم آگاه سازی caching آماده می شود. برای آشنائی با نحوه عملكرد سيستم فوق يك نمونه مثال را با يكديگر دنبال می نمائيم .
فرض كنيد قصد داريم نتيجه query زير را cache نمائيم .

  SELECT * FROM Employees

query فوق ركوردهای موجود در جدول Employees را بازيابی می نمايد . برای آگاهی از اين كه چه زمانی يك ركورد جديد در جدول Employees درج ، حذف و يا ويرايش شده است تا بر اساس آن شی cache شده غير معتبر گردد ، از يك trigger استفاده می شود . trigger مورد نظر بر روی جدول Employees و توسط برنامه كمكی aspnet_regsql ايجاد می شود .

ايجاد يك triggerبر روی جدول Employees

 CREATE TRIGGER dbo.[Employees_AspNet_SqlCacheNotification_Trigger]
 ON [Employees]
   FOR INSERT, UPDATE, DELETE AS BEGIN
     SET NOCOUNT ON
     EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N'Employees'
 END

بدين ترتيب ، پس از بروز هر گونه تغيير بر روی جدولی كه مانيتور می گردد ، يك stored procedure با نام AspNet_SqlCacheUpdateChangeIdStoredProcedure فعال و changeId سطر مربوطه را در جدول آگاه سازی تغييرات اضافه می نمايد .

     AspNet_SqlCacheUpdateChangeIdStoredProcedure

 CREATE PROCEDURE dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure
   @tableName NVARCHAR(450)
  AS
    BEGIN
       UPDATE dbo.AspNet_SqlCacheTablesForChangeNotification WITH (ROWLOCK)
       SET changeId = changeId + 1
       WHERE tableName = @tableName
   END
GO

در جدول AspNet_SqlCacheTablesForChangeNotification برای هر جدولی كه قصد مانيتورينگ آن را داريم يك ركورد ايجاد می گردد. پس از بروز تغيير در جدول ( نظير درج يك ركورد جديد ) ، يك واحد به ستون changeId اضافه می گردد . ASP. NET به صورت دوره ای اين جدول و مقادير مربوط به changeId را بررسی و در صورتی كه مقدار فيلد فوق تغيير نمايد ، از بروز تغييرات در جدول مورد نظر آگاه می گردد .
روش فوق يكی از محدوديت های غيرمعتبرسازی caching در SQL Server 2000 و SQL Sever 7 را نشان می دهد : هر نوع تغيير بر روی جدول باعث غيرمعتبر شدن هرگونه query بر روی جدول می گردد . به عنوان نمونه فرض كنيد كه از query زير استفاده كرده باشيم :

  SELECT * FROM Employees WHERE City='City1'

پس از اجرای query فوق ، ركورد كاركنانی كه فيلد شهر آنان معادل city1 باشد ، cache می گردد . در چنين وضعيتی اگر ركورد يكی از كاركنان كه فيلد city آن معادل city1 نباشد تغيير يابد ( ركورد اين نوع كاركنان قبلا" cache نشده است ) ، سيستم آگاه سازی caching اطلاعات مربوط به غيرمعتبرسازی داده cache شده را ارسال می نمايد( غيرمعتبر شدن داده موجود در cache كه در عمل هيچكدام از ركوردهای آن در جدول Employees تغيير نكرده اند ) .
تشخيص و پيگيری اين كه كدام تغيير می تواند زمينه غيرمعتبر سازی يك داده cache شده را فراهم نمايد مستلزم انجام عمليات سنگينی توسط SQL Server 2000 است ( اين كار در SQL Server 2005 امكان پذير است ) .

ايجاد cache dependency

در بخش قبل با نحوه پيكربندی يك بانك اطلاعاتی برای حمايت از سيستم آگاه سازی SQL Server آشنا شديم .پس از فراهم شدن زيرساخت لازم می توان از آن در برنامه های وب با استفاده از يكی از روش های زير استفاده نمود .
• data caching از طريق برنامه : برای data caching از طريق كد لازم است كه يك شی جديد SqlCacheDependency ايجاد و آن را با استفاده از متد Cache.Insert به cache اضافه نمود ( مشابه file dependency ) .
در constructor شی SqlCacheDependency می بايست دو رشته را مشخص كرد . اولين رشته نام بانك اطلاعاتی ( توسط عنصر <add> در بخش <sqlCacheDependency> فايل web.config مشخص شده است ) و دومين رشته ، نام جدولی است كه قصد مانيتورينگ تغييرات آن را داريم.
در اولين مرحله يك وابستگی برای جدول Employees بانك اطلاعاتی Northwind ايجاد و در مرحله بعد آيتم مورد نظر را به cache اضافه می نمائيم . حضور آيتم فوق مشروط به عدم بروز تغييرات در جدول Employees است . در صورت بروز تغييرات در جدول فوق ، اعتبار داده cache شده به اتمام رسيده و از cache خارج می گردد .
كد زير نحوه انجام اين كار را نشان می دهد .

Dim empDependency As New SqlCacheDependency("Northwind", "Employees")
Cache.Insert("Employees", dsEmployees, empDependency)

• output caching : بدين منظور لازم است كه خصلت SqlCacheDependency به دايركتيو OutputCache معرفی شود . مقدار خصلت فوق شامل نام بانك اطلاعاتی وابسته و جدول مورد نظر است كه توسط يك colon از يكديگر جدا شده اند .
كد زير نحوه انجام عمليات فوق را نشان می دهد .

 <%@ OutputCache Duration="600" SqlDependency="Northwind:Employees" VaryByParam="none" %>

• يك كنترل منبع داده: از روش فوق می توان به همراه كنترل های SqlDataSource و ObjectDataSource استفاده كرد . كد زير نحوه انجام اين كار را نشان می دهد .

 <asp:SqlDataSource EnableCaching="True" SqlCacheDependency="Northwind:Employees" ... />

بررسی‌ يك مثال كاربردی

در اين مثال پس از فعال كردن سيستم آگاه سازی caching بر روی جدول Employees بانك اطلاعاتی Northwind ، يك داده فرضی در cache ذخيره می گردد . در صورت بروز هر گونه تغيير در جدول Employees ، اعتبار داده cache شده با توجه به مدت زمان تعريف شده توسط خصلت pollTime عنصر <sqlCacheDepency> موجود در فايل web.config به اتمام خواهد رسيد .
بدين منظور عمليات مورد نياز جهت پياده سازی را در دو فاز مختلف دنبال می نمائيم . فاز اول : ايجاد زيرساخت لازم برای استفاده از سيستم آگاه سازی caching
در اين مثال برای فعال كردن سيستم آگاه سازی caching بر روی بانك اطلاعاتی Northwind و ريجستر كردن جدول Employees به منظور حمايت از سيستم آگاه سازی caching توسط برنامه خط دستوری aspnet_regsql.exe از سوئيچ C - استفاده شده است تا در مقابل مشخص كردن نام كاربر ، رمز عبور و نام سرويس دهنده از يك Connection string استفاده گردد . مرحله اول : فعال كردن سيستم آگاه سازی caching بر روی بانك اطلاعاتی Northwind به كمك برنامه خط دستوری aspnet_regsql.exe

  C:\WINDOWS\Microsoft. NET\Framework\V2.0.50727>aspnet_regsql -ed
    -C "Data Source=SRCOSERVER\SQLEXPRESS;Initial Catalog=NORTHWND;Integrated Security=True"

  Enabling the database for SQL cache dependency.
 ....
 Finished.

پس از اجرای دستور فوق ، يك جدول جديد با نام SqlCacheTablesForChangeNotification به بانك اطلاعاتی Northwind اضافه می گردد. جدول فوق دارای سه ستون notificationCreated ، tableName و changeId است و از آن برای پيگيری انجام تغييرات استفاده می گردد . مرحله دوم : ريجستر كردن جدول Employees كه نيازمند حمايت از سيستم آگاه سازی caching است .

  C:\WINDOWS\Microsoft. NET\Framework\V2.0.50727>aspnet_regsql -et
    -C "Data Source=SRCOSERVER\SQLEXPRESS;Initial Catalog=NORTHWND;Integrated Security=True"
    -t Employees

  Enabling the table  for SQL cache dependency.
 .
 Finished.

مرحله سوم : فعال كردن polling از طريق فايل web.config
فعال كردن polling از طريق فايل web.config

فعال كردن pollingاز طريق فايل web.config

<configuration>
   <connectionStrings>
       <add name="NORTHWNDConnectionString"
            connectionString="Data Source=SRCOSERVER\SQLEXPRESS;
            Initial Catalog=NORTHWND;Integrated Security=True"/>
   </connectionStrings>
 <system.web>
<caching>
  <sqlCacheDependency enabled="true" pollTime="15000" >
    <databases>
         <add name="Northwind" connectionStringName="
NORTHWNDConnectionString" />
   </databases>
</sqlCacheDependency>

</caching>
...
</system.web>
</configuration>

فاز دوم : استفاده از زيرساخت ايجاد شده سيستم آگاه سازی caching در برنامه
در اين برنامه از دو button به نام " تغيير جدول " و " بررسی آيتم cache شده " استفاده شده است . با استفاده از دكمه "بررسی آيتم cache شده " ، حضور آيتم مورد نظر در cache بررسی و پيام مناسب در خروجی نمايش داده می شود . در صورت كليك بر روی دكمه "تغيير جدول " ، يكی از ركورهای موجود در جدول Employees بانك اطلاعاتی Northwind تغيير يافته و بهانه خارج شدن داده cache شده از حافظه ايجاد می گردد .
كد برنامه فوق در جدول زير نشان داده شده است .

 ايجاد cachedependencyدر بانك اطلاعاتی NORTHWND

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>  
<%@ import Namespace="system.Data" %>
<%@ import Namespace="system.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>
<Script runat="server">
 Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  If Not Me.IsPostBack Then
    lblInfo.Text &= "ايجاد آيتم وابسته<br />"
     Cache.Remove("CachedItem")
   '  Employees  ايجاد يك وابستگی برای جدول
     Dim dependency As New SqlCacheDependency("Northwind", "Employees")
     Dim dt As DataTable = GetEmployeeTable()
     lblInfo.Text &= "اضافه كردن آيتم مورد نظر بهcache<br />"
     Cache.Insert("CachedItem", dt, dependency)
  End If
 End Sub
  ' =================================================================
Private connectionString As String =_
          WebConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
 Function GetEmployeeTable() As DataTable
  Dim con As New SqlConnection(connectionString)
  Dim sql As String = "SELECT * FROM Employees"
  Dim da As New SqlDataAdapter(sql, con)
  Dim ds As New DataSet()
  da.Fill(ds, "Employees")
  Return ds.Tables(0)
End Function
  ' ==================================================================
 Sub cmdGetItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdGetItem.Click
 If Cache("CachedItem") Is Nothing Then
   lblInfo.Text &= "آيتم مورد نظر درcache موجود نمی باشد<br />"
 Else
  lblInfo.Text &= "آيتم مورد نظر همچنان درcache موجود است<br />"
 End If
End Sub
  ' =================================================================
Sub cmdModify_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdModify.Click
 Dim con As New SqlConnection(connectionString)
' بهنگام سازی بانك اطلاعاتی
 Dim sql As String = "UPDATE Employees SET LastName='sakha ravesh' WHERE LastName='srco'"
 Dim cmd As New SqlCommand(sql, con)
 Try
   con.Open()
   cmd.ExecuteNonQuery()
 Finally
 con.Close()
 End Try
 lblInfo.Text &= "بهنگام سازی بانك به تمامرسيد ، تا اتمام زمانpolling منتظر بمانيد<br />"
End Sub
 ' =================================================================
</Script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
  <head id="Head1" runat="server">
     <title>Untitled Page</title>
  </head>
  <body style="font-family: Tahoma">
     <form id="form1" runat="server">
       <div>
           <asp:Button ID="cmdModify" runat="server" Height="24px"  Text="تغيير جدول"
                              Width="103px" Font-Names="Tahoma" />
           <asp:Button ID="cmdGetItem" runat="server" Height="24px"
                              Text="بررسی آيتمcache شده"
                              Width="180px" Font-Names="Tahoma" /><br /><br />
           <asp:Label ID="lblInfo" runat="server" BackColor="LightYellow" BorderStyle="Groove"
                            BorderWidth="2px" Font-Names="Tahoma" Font-Size="X-Small" Height="192px"
                            Width="536px"></asp:Label>
       </div>
    </form>
   </body>
</html>

توضيحات :

• در زمان فراخوانی برنامه فوق از طريق روتين Page_laod عمليات زير انجام می شود :
- ايجاد يك شی وابسته برای جدول Employees بانك اطلاعاتی Northwind
- درج dataset حاوی ركوردهای بازيابی شده از جدول Employees در cache
- نمايش پيام های مناسب در خروجی به كمك كنترل سرويس دهنده label ( با نام lblInfo )
• روتين cmdGetItem_Click ، وجود آيتم مورد نظر را در Cache بررسی و در صورتی كه اين آيتم در cache موجود نباشد يك پيام خاص از طريق كنترل سرويس دهنده label در خروجی نمايش داده می شود . در صورت وجود آيتم مورد نظر در cache ، مقدار آن از cache بازيابی و يك پيام خاص از طريق كنترل سرويس دهنده label در خروجی نمايش داده می شود .
• روتين cmdModify_Click ، مسئوليت ايجاد تغيير در جدول Employees بانك اطلاعاتی Northwind را برعهده دارد .
سيستم آگاه سازی caching در SQL Server 2000 و SQL Server 2005
سيستم آگاه سازی caching در SQL Server 2005 وضعيت بمراتب بهتری را نسبت به SQL Server 2000 پيدا كرده است . چراكه زيرساخت سيستم فوق از طريق يك سيستم ارسال و دريافت پيام موسوم به Service Broker در بانك اطلاعاتی تعبيه شده است .
Service Broker يكی از ويژگی های جديد ارائه شده در SQL Server 2005 است . سيستم فوق ، در واقع يك فريمورك ارسال و دريافت پيام توزيع شده را ارائه می نمايد . با استفاده از ويژگی فوق می توان قابليت های متعددی را به بانك اطلاعاتی اضافه نمود . Service Broker از سيستم ذخيره سازی صف ( FIFO ) استفاده می نمايد و يك لينك ارتباطی بين ارسال كننده پيام و دريافت كننده پيام ايجاد می نمايد . سيستم فوق مديريت صف ها را برعهده داشته و شامل اشياء بانك اطلاعاتی نظير جداول ، view و stored procedure می باشد .
پياده كنندگان با استفاده از دستور CREATE EVENT NOTIFICATION می توانند به SQL Server 2005 آموزش دهند كه در صورت بروز رويدادهائی خاص اطلاعات لازم را برای سيستم آگاه سازی caching ارسال نمايد .
ASP. NET از يك زاويه ديگر به اين موضوع نگاه می كند . پس از مشخص شدن يك query ، فناوری ASP. NET بطور اتوماتيك به SQL Server 2005 اعلام می نمايد كه اطلاعات آگاه سازی را برای هر نوع عملياتی كه می تواند بر روی نتيجه query تاثيرگذار باشد ارسال نمايد . هر مرتبه كه يك عمليات خاص انجام شود ، SQL Server مشخص می نمايد كه آيا اين عمليات می تواند يك دستور ريجستر شده را تحت تاثير قرار دهد و يا خير ؟ در صورتی كه عمليات انجام شده بتواند بر روی يك دستور ريجستر شده تاثيرگذار باشد ، SQL Server يك پيام آگاه سازی را ارسال و فرآيند آگاه سازی را متوقف می نمايد .
سيستم آگاه سازی Caching در SQL Server 2005 نسبت به SQL Server 2000 دارای مزايای متعددی است :
• آگاه سازی بر اساس جزئيات بيشتری از اطلاعات . در مقابل غيرمعتبر سازی شی cache شده در زمان بروز تغييرات در يك جدول ، SQL Server 2005 صرفا" يك شی را زمانی غيرمعتبر می كند كه عملياتی نظير درج ، بهنگام سازی و حذف بر روی سطر مورد نظر انجام شده باشد .
• عدم ضرورت انجام عملياتی خاص برای پيكربندی و آماده سازی سيستم آگاه سازی . برای بهره برداری از سيستم آگاه سازی caching در SQL Server 2005 ضرورتی به اجرای برنامه خط دستوری aspnet_regsql و يا ذخيره تنظيمات pooling در فايل web.config وجود ندارد .
سيستم آگاه سازی فعاليت خود را بر اساس يك SELECT query و يا stored procedure آغاز می كند . در چنين مواردی ، استفاده از SELECT query محدوديت های مختص به خود را داشته و از قوانين زير تبعيت می نمايد :
• برای اجرای query بر روی يك جدول می بايست نام آن به صورت Owner].table ] مشخص گردد . به عنوان نمونه dbo.Employees ( صرفا" نمی بايست نام جدول Employees آورده شود . )
• در query مورد نظر نمی بايست از توابعی نظير Conut ، MAX ، MIN و يا AVERAGE استفاده گردد .
• نمی توان با استفاده از wildcard تمامی ستون ها را انتخاب نمود ( نظير SELECT * FROM Employees ) . در مقابل ، می بايست نام هر ستون دقيقا" مشخص گردد تا SQL Server بتواند تغييرات آنها را پيگيری و آندسته از ستون هائی را كه در نتيجه query تاثيرگذار هستند تشخيص دهد .
شكل صحيح استفاده از دستور Select به صورت زير است .

SELECT EmployeeID, FirstName, LastName, City FROM dbo.Employees

موارد فوق مهمترين قوانين موجود در اين رابطه می باشند و مجموعه كامل تری را می توان بر روی msdn مشاهده نمود . در صورت عدم رعايت يكی از قوانين اشاره شده با يك پيام خطاء مواجه نخواهيم شد و در عمل سيستم آگاه سازی caching وظايف خود را به درستی انجام نخواهد داد . توجه داشته باشيد كه پيام آگاه سازی بلافاصله پس از ريجستركردن دستور ، ارسال و آيتم cache شده غيرمعتبر می گردد .

مقداردهی اوليه سرويس caching

قبل از اين كه بتوان از سيستم آگاه سازی caching در SQL Server 2005 استفاده كرد، می بايست عمليات زير را انجام داد :
• فعال كردن SQL Server Service Broker . در صورتی كه Service Broker برای بانك اطلاعاتی مورد نظر فعال نشده باشد در زمان اجرای يك برنامه وب كه قصد استفاده از سيستم آگاه سازی caching در SQL Server 2005 را دارد ‌، با پيام خطاء زير مواجه خواهيم شد :

Server Error in '/WebSite4' Application.
The SQL Server Service Broker for the current database is not enabled, and as a result query notifications are not supported.  Please enable the Service Broker for this database if you wish to use notifications.

• برای حل مشكل فوق كافی است كه Service Broker را برای بانك اطلاعاتی مورد نظر فعال نمود . بدين منظور می توان از دستور زير در SQL Server استفاده نمود :

ALTER DATABASE [Northwnd] SET  ENABLE_BROKER ;
GO

• پس از اجرای دستور فوق اين احتمال وجود خواهد داشت كه مجددا" با يك پيام خطاء ديگر مواجه شويم :

Msg 9776, Level 16, State 1, Line 2

Cannot enable the Service Broker in database "Northwnd" because the Service Broker
GUID in the database (B4201B09-6358-4C65-8457-D6F50004A4D9) does not match the one
 in sys.databases (2527A339-BFB3-45C6-978D-412C4FA557CB).

Msg 5069, Level 16, State 1, Line 2

ALTER DATABASE statement failed.

• علت بروز اين خطاء بدين دليل است كه عملياتی بر روی بانك اطلاعاتی ( به عنوان نمونه Northwind ) بدون دنبال نمودن صحيح فرآيندهای آن انجام شده است . به عنوان مثال جايگزينی فايل های mdf . و ldf . از بانك های ديگر . توجه داشته باشيد كه می بايست همواره از رويه ای صحيح برای move و copy بانك اطلاعاتی استفاده كرد ( استفاده از attach/detach و يا backup/restore ) .
با توجه به موارد فوق نمی توان broker موجود را بر روی بانك اطلاعاتی Northwind فعال نمود و می بايست يك نمونه جديد را با استفاده از دستور زير ايجاد نمود :

ALTER DATABASE [Northwnd] SET NEW_BROKER ;
GO

• برای اطمينان از فعال شدن service broker می توان از query زير استفاده كرد. در صورتی كه مقدار يك برگرداند شود ، اين سرويس بر روی بانك اطلاعاتی Northwind فعال شده است .

select is_broker_enabled from sys.databases where name = 'Northwnd'

• فراخوانی متد SqlDependency.Start . متد فوق مسئوليت مقداردهی اوليه سرويس listening بر روی‌ سرويس دهنده وب را برعهده دارد .

Dim connectionString As String = _
WebConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
SqlDependency.Start(connectionString)

• فراخوانی متد فوق صرفا" يك مرتبه در مدت زمان حيات برنامه وب انجام می شود و بهتر است كه در متد Application_Start فايل global.asax قرار داده شود تا زمينه فعال شدن اتوماتيك آن فراهم گردد . همچنين می توان از متد stop برای توقف listener استفاده نمود .

ايجاد cache dependency

برای استفاده از cache dependency در SQL Server 2005 به يك گرامر متفاوت نياز است كه صرفا" شامل مشخص كردن نام جدول و بانك اطلاعاتی نمی باشد . در مقابل ، SQL Server می بايست از دستور واقعی آگاهی يافته و نسبت به آن شناخت داشته باشد .
در صورت فعال كردن caching از طريق كد ، می بايست با استفاده از constructor كه يك شی SqlCommand را به عنوان پارامتر دريافت می نمايد اقدام به ايجاد SqlCacheDependency كرد .
كد زير نحوه انجام اين كار را نشان می دهد .

Dim con As New SqlConnection(connectionString)
Dim query As String ="SELECT EmployeeID, FirstName, LastName, City FROM dbo.Employees"
Dim cmd As New SqlCommand(query, con)
Dim adapter As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
adapter.Fill(ds, "Employees")
Dim empDependency As New SqlCacheDependency(cmd)
Cache.Insert("Employees", ds, empDependency)

در صورت استفاده از دايركتيو OutputCache و يا يك كنترل منبع داده ، ASP. NET مسئوليت ريجستر كردن را بر عهده می گيرد و پياده كنندگان می بايست صرفا" مقدار CommandNotification را مشخص نمايند .

 <%@ OutputCache Duration="600" SqlDependency="CommandNotification" VaryByParam="none" %>

بررسی‌ يك مثال كاربردی
كد زير نحوه ايجاد cache dependency در SQL Server 2005 و بر روی بانك اطلاعاتی Northwind را نشان می دهد . پس از فعال شدن برنامه فوق و از طريق روتين page_load ، يك وابستگی برای جدول customers ايجاد ( ماحصل اجرای دستور Select ) و ماحصل آن در cache ذخيره می گردد . در صورت بروز هرگونه تغيير در فيلد ContactName جدول customers ( اين كار توسط روتين cmdModify_Click انجام می شود ) اعتبار داده cache شده بطور اتوماتيك و از طريق سيستم آگاه سازی caching در SQL Server 2005 به اتمام می رسد .

 ايجاد cachedependencyدر SQL Server 2005  

<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" Debug="true"%>
<%@ import Namespace="system.Data" %>
<%@ import Namespace="system.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>
'===================================================================
 <script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  If Not Me.IsPostBack Then
    SqlDependency.Start(connectionString)
    lblInfo.Text &= "ايجاد آيتم وابسته<br />"
    Cache.Remove("Customers")
    Dim dt As DataTable = GetTable()
    lblInfo.Text &= "اضافه كردن آيتم مورد نظر بهcache<br />"
    Cache.Insert("Customers", dt, dependency)
 End If
End Sub
'===================================================================
Private dependency As SqlCacheDependency
Private connectionString As String = _
WebConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
Private Function GetTable() As DataTable
  Dim con As New SqlConnection(connectionString)
  Dim sql As String = "SELECT ContactName FROM dbo.Customers"
  Dim da As New SqlDataAdapter(sql, con)
  ' ايجاد يك وابستگی برای جدول 
  dependency = New SqlCacheDependency(da.SelectCommand)
  Dim ds As New DataSet()
  da.Fill(ds, "Customers")
  Return ds.Tables(0)
End Function
'===================================================================
Protected Sub cmdGetItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdGetItem.Click
 If Cache("Customers") Is Nothing Then
   lblInfo.Text &= "آيتم مورد نظر درcache موجود نمی باشد<br />"
 Else
  lblInfo.Text &= "آيتم مورد نظر همچنان درcache موجود است<br />"
 End If
End Sub
'===================================================================
Protected Sub cmdModify_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdModify.Click
Dim con As New SqlConnection(connectionString)
Dim sql As String = "UPDATE dbo.Customers SET ContactName='Test Contact_Name' WHERE CustomerID='WOLZA'"
Dim cmd As New SqlCommand(sql, con)
Try
  con.Open()
  cmd.ExecuteNonQuery()
Finally
con.Close()
End Try
lblInfo.Text &= " بهنگام سازی به اتمام رسيد<br />"
End Sub
'===================================================================
</script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
  <head id="Head1" runat="server">
     <title>Untitled Page</title>
  </head>
  <body style="font-family: Tahoma">
     <form id="form1" runat="server">
       <div>
           <asp:Button ID="cmdModify" runat="server" Height="24px"  Text="تغيير جدول"
                              Width="103px" Font-Names="Tahoma" />
           <asp:Button ID="cmdGetItem" runat="server" Height="24px"
                              Text="بررسی آيتمcache شده"
                              Width="180px" Font-Names="Tahoma" /><br /><br />
           <asp:Label ID="lblInfo" runat="server" BackColor="LightYellow" BorderStyle="Groove"
                            BorderWidth="2px" Font-Names="Tahoma" Font-Size="X-Small" Height="192px"
                            Width="536px"></asp:Label>
       </div>
    </form>
   </body>
</html>

مشكلات احتمالی در خصوص سيستم آگاه سازی caching

در صورتی كه هرگز اعتبار آيتم cache شده به پايان نرسد ، سرويس polling در ASP. NET يك پيام غيرمعتبرسازی را دريافت نمی نمايد . اين مشكل می تواند دلايل متعددی داشته باشد . فعال نشدن CLR برای SQL Server يكی از متداولترين مشكلات موجود در اين رابطه است .
رويه ای كه پيام های آگاه سازی را ارسال می نمايد يك رويه دات نت است و به حمايت آن نياز دارد . برای فعال كردن CLR ، می توان از پنجره خط دستور ويژوال استوديو دات نت 2005 استفاده كرد و دستور SqlCmd.exe را تايپ كرد .
كد زير نحوه فعال كردن دستور فوق را برای SQL Server 2005 Express Edition نشان می دهد :

  SqlCmd -S localhost\SQLEXPRESS

در صورت استفاده از نسخه كامل SQL Server 2005 ، لازم نيست از instance name استفاده شود ( استفاده از localhost در مقابل localhost\SQLEXPRESS ) .
همچنين ممكن است با توجه به محل نصب بانك اطلاعاتی لازم باشد كه نام سرويس دهنده تغيير يابد . در دستور قبلی ، فرض بر اين است كه بانك اطلاعاتی بر روی كامپيوتر جاری نصب شده است .
برنامه كاربردی SqlCmd.exe يك پرامپت دستوری را ارائه می نمايد كه می توان از آن به منظور درج دستورات SQL استفاده كرد . برای فعال كردن CLR از دستورات زير استفاده می گردد .

EXEC sp_configure 'show advanced options', '1'
GO
RECONFIGURE
GO
EXEC sp_configure 'clr enabled', 1
GO
RECONFIGURE

در ادامه و با تايپ دستور quit می توان از برنامه SqlCmd.exe خارج شد.
در صورتی كه اعتبار آيتم cache شده بلافاصله به اتمام برسد ، اين احتمال وجود دارد كه از قوانين اشاره شده در ارتباط با نوشتن query تبعيت نشده باشد .

سخن آخر

طراحان و پياده كنندگان برنامه های وب با بكارگيری مجموعه ای از ترفندها ، فناوری ها و رعايت برخی نكات كليدی می توانند برنامه هائی را با كارآئی مطلوب طراحی و پياده سازی نمايند . با توجه به جايگاه مهم لايه داده در برنامه های وب ، می بايست بر روی لايه فوق با دقت بيشتری متمركز و اقدامات لازم را در زمان طراحی و پياده سازی انجام داد .
پياده كنندگان برنامه های وب با نوشتن چندين خط كد اضافه می توانند قابليت رشد و كارآئی برنامه های خود را بطرز چشمگيری افزايش دهند .
استفاده از ابزارهای تست و پروفايلينگ حداقل شرايط لازم به منظور بررسی قابليت های يك برنامه وب كارآ را فراهم می نمايد تا بتوان قبل از عملياتی شدن مشكلات و گره های حساس تاثيرگذار بر روی‌ كارآئی برنامه را شناسائی و در جهت رفع آنها تلاش كرد .




نظرات کاربران
ارسال نظر
با تشکر، نظر شما پس از بررسی و تایید در سایت قرار خواهد گرفت.
متاسفانه در برقراری ارتباط خطایی رخ داده. لطفاً دوباره تلاش کنید.
مقالات مرتبط