کش در Hibernate چگونه پیاده سازی میشود؟

 من ارسلان میربزرگی، در این مقاله قصد دارم تا شما را با مفهوم Hibernate در جاوا و استفاده از کش در آن آشنا کنم. در دوره های قبلی برنامه نویسی جاوا، با مفاهیم پایه مربوط به جاوا آشنا شدید و اکنون مفاهیم جدیدتری را در این مقاله برای شما مطرح خواهم کرد.
 Hibernate

Caching در Hibernate

یکی از قابلیت‌های دیگری که توسط Hibernate  ارائه می‌شود، پشتیبانی از Caching است. با استفاده از این قابلیت، ورود درخواست‌ها به بانک اطلاعاتی کاهش می‌یابد و کارایی برنامه افزایش پیدا می‌کند. Cache بین برنامه و بانک اطلاعاتی قرار می‌گیرد و مراجعات مکرر به بانک اطلاعاتی را تا حد امکان کاهش می‌دهد. به طور خلاصه می‌توان چنین گفت که Cache در Hibernate  با کاهش ورود درخواست‌ها به بانک اطلاعاتی، باعث افزایش کارایی برنامه می‌شود.
caching in hibernate

Cache در لایه سطح دوم Hibernate

در شکل زیر مشاهده می‌کنید که Cache در Hibernate  در 2 سطح به کار گرفته می‌شود. هدف از اراده این مقاله نیز، بررسی Cache در سطح دوم Hibernate است. به این منظور پس از ارائه توضیحات بیشتر، ابتدا مقدمه کوتاهی در مورد Cache در سطح اول Hibernate  به شما ارائه می‌دهیم و پس از آن در مورد Cache در سطح دوم Hibernate  صحبت خواهیم کرد.

کش سطح اول یا First level Cache

Cache در سطح اول، در سطح یک session فعال است و در تمامی درخواست‌هایی که رد و بدل می شوند استفاده می‌شود. این سطح از Cache ، به طور خودکار، تمامی درخواست را قبل از فرستادن به سمت بانک اطلاعاتی، پردازش می کند و از تبادل تراکنش تکراری با بانک اطلاعاتی جلوگیری می‌کند. ویژگی های Cache در سطح اول را می‌توان در موارد زیر خلاصه کرد:
  • این سطح از Cache به طور پیش فرض، در سطح یک session فعال است.
  • نیاز به اعمال تنظیمات خاصی از طرف برنامه نویسان ندارد.
  • برنامه نویسان قادر به غیرفعال کردن این سطح نیستند.
  • این Cache در تمام طول کارکرد session در دسترس است.
  • اگر session غیرفعال شود، تمام اشیاء کش شده نیز از بین خواهند رفت.
  • اشیاء کش شده نمی توانند بین چند session به اشتراک گذاشته شوند.
در شکل زیر، مراحل بارگذاری یک شی را مشاهده می‌کنید. در این شکل، Hibernate  پس از گرفتن درخواست، ابتدا موجود بودن شی درخواستی بر روی session را بررسی می‌کند. در صورت موجود بودن این شی، دیتا از session بازخوانی شده و برگردانده می‌شود. در صورتی که شی موجود نباشد، درخواست به سمت بانک اطلاعاتی رفته و داده‌ها از بانک اطلاعاتی استخراج می‌شوند. در این حالت Cache نیز ساخته خواهد شد.
caching in hibernate

کش سطح دوم یا Second level Cache

Cache در سطح دوم، به شی Session Factory وابسته است و در هنگام اجرای تراکنش ها، تمامی اشیاء را در سطح Factory بارگذاری می‌کند. در نتیجه، این اشیاء به یک کاربر محدود نبوده و در تمام سطح برنامه در دسترس خواهند بود. ویژگی های Cache در سطح دوم را می ‌توان در موارد زیر خلاصه کرد:
  • این سطح از Cache به طور پیش فرض، در سطح شی Session Factory وجود دارد.
  • نیاز به اعمال تنظیمات خاصی از طرف برنامه نویسان دارد.
  • استفاده از این کش اختیاری است.
  • برای این کش، پیاده سازی های مختلفی مانند EH Cache, OS Cache, SWARM Cache, JBOSS Cache وجود دارد.
مراحل بارگذاری با این کش، مشابه کش سطح اول است. تنها تفاوت آنها در این است که اگر داده مورد نظر در سطح Session پیدا نشود، جستجو در سطح Session Factory که فراگیرتر است انجام می شود، و در صورتی که جستجو در  Session Factory نیز نتیجه ای در برنداشت، درخواست به بانک اطلاعاتی ارسال می‌شود.
caching in hibernate

مثال :

می‌خواهیم پیاده سازی کش سطح دوم با استفاده از EH Cache را مورد بررسی قرار دهیم. در این برنامه کش سطح دوم Hibernate  را فعال کرده و از آن استفاده می‌کنیم. پس از آن، dependency تحت عنوان Hibernate -ehcache را به  pom پروژه اضافه می‌کنیم.
caching in hibernate
در تنظیمات Hibernate  نیز باید تغییراتی انجام دهیم. با فرض singleton بودن factory مقدار factory class را برابر singleton EH Cache Reign Factory قرار می‌دهیم و کش سطح دوم و کش query را فعال کرده و تنظیمات اختصاصی EH Cache را نیز باید به صورت یک فایل مجزا xml به Hibernate  معرفی کنیم.
caching in hibernate
حالا در فایل تنظیمات ( ehcache.xml)  باید این موارد تعیین شوند.
  • در تگ <diskstore> مسیری برای نگهداری محتوای cache شده تعیین می‌شود. در واقع این cache در حافظه اصلی انجام می‌شود و این مسیر، جایی است که در صورت overflow یا سرریز شدن دیتاها از آن استفاده می‌شود.
  • در تگ بعدی یعنی تگ <default cache> برای cache تمامی entity ها، تنظیمات پیش فرض یکسانی اعمال می‌شود اما اگر یک entity بخواهد تنظیمات متفاوتی را داشته باشد، باید این تنظیمات اختصاصی در یک تگ <cache> اختصاصی، به Hibernate  معرفی شود.
در عنصر persistence، استراتژی cache برابر Local Temp Swap تعیین شده است. به این ترتیب Hibernate  از حافظه موقتی استفاده می‌کند و به طور خودکار با ریسِت شدن برنامه، خالی می‌شود.
caching in hibernate
در هر بخشی که قرار است کش روی آن اعمال شود یک انوتیشن @cache قرار می گیرد که در آن، علاوه  بر اعلام استراتژی کش، قسمتی از فایل تنظیمات ( ehcache.xml)  برای اعمال تنظیمات معرفی می‌شود.
caching in hibernate
caching in hibernate
در این مرحله به سراغ مراحل اجرایی برنامه می‌رویم. به این منظور، کد مربوط به 2 شی را در شرایط مختلف بارگذاری می‌کنیم اما به صورت همزمان، 2 session مجزا ( session B ، session A ) را نیز بر روی Session Factory باز می‌کنیم. Session Factory دارای متدی به نام get Statistics () است. این متد  حاوی اطلاعات آماری در زمینه تمامی وقایعی است که ممکن است روی یک Session Factory رخ بدهد.
caching in hibernate
برای استفاده از این اطلاعات، باید آنها را فعال کرد. 3 مورد از این اطلاعات در زمینه کش سطح دوم هستند و در متد print Date() که در این کلاس ذکر کردیم، استفاده شده‎‌اند.
متد get Second Level Cache Hit Count() ، تعداد دفعات استخراج موقت یک entity از کش را بازمیگرداند. زمانی که یک رکورد درخواست می شود، ابتدا به کش رجوع می شود و اگر رکورد مورد نظر در کش وجود داشته باشد، از آن استفاده می‌شود و یک واحد هم به این عدد افزوده می‌شود.
متد get Second Level Cache Miss Count() ، تعداد دفعات مراجعه ناموفق به به کش را برمیگرداند. به عبارتی این متد، بیانگر تعداد دفعاتی است که مراجعه به کش انجام شده است اما رکورد مورد نظر در کش وجود نداشت است.
متد get Second Level Cache Put Count() ، تعداد دفعاتی که entity در کش قرار داده شده را برمیگرداند. این به این معنا است که زمانی که یک entity از بانک استخراج می‌شود، نسخه‌ای از آن در کش قرار گرفته و این عدد یک واحد افزایش می‌یابد.
caching in hibernate
متد دیگری نیز به نام متد  get Entity Fetch Count در اینجا استفاده شده است. این متد، به تعداد دفعات ارسال درخواست  Fetch به بانک اطلاعاتی اشاره دارد.
caching in hibernate
روند اجرای برنامه را از نقطه تعیین شده با breakpoint بررسی می‌کنیم. رکوردی از جدول Employee را از قسمت session A لود می کنیم. سپس با متدی که قبلا نوشته‌ایم، محتوای رکورد را استخراج می‌کنیم و اطلاعات آماری مربوط به کش را چاپ می‌کنیم. چاپ متن query در کنسول به معنای استخراج مستقیم اطلاعات از بانک است. همانطور که در اطلاعات آماری نیز این نکته که درخواست به سمت بانک ارسال شده است، قابل مشاهده است. تعداد دفعات برداشت از کش یا Hibernate  برابر با صفر است. زیرا تا قبل از این، چنین رکوردی در کش موجود نبوده است. تعداد دفعات مراجعه ناموفق به کش نیز برابر 1 و تعداد دفعات ذخیره شدن در کش هم برابر 1 می شود. زیرا از این لحظه به بعد این رکورد در کش ذخیره می‌شود.
caching in hibernate
در مرحله دوم، مجددا همان رکورد مرحله اول را لود می‌کنیم. تعداد دفعات استخراج از بانک، تغییری نمی‌کند چون این رکورد قبلا لود شده است و در کش موجود است. در واقع هیچ عملیاتی انجام نمی‌شود و در پارامترهای مربوط به کش هم تغییری رخ نمی‌دهد.
caching in hibernate
در مرحله سوم، توسط دستور evict، entity لود شده را از روی session حذف می‌کنیم. در کش سطح اول، توسط چنین دستوری، کش سطح اول که کش پیش فرض و در سطح session است، پاک می‌شود اما در اینجا با حذف entity از روی session ، کش سطح دوم که در سطح Session Factory قرار دارد، پابرجا خواهد ماند. به اطلاعات چاپ شده دقت کنید. این اطلاعات، تفاوتی با مرحله قبلی ندارند و در واقع با از بین رفتن اطلاعات موجود در session، اطلاعات کش سطح دوم از بین نخواهد رفت.
caching in hibernate
در مرحله بعدی، رکورد جدیدی را روی این session لود می‌کنیم. مشاهده می‌کنیم که تعداد دفعات استخراج به میزان یک واحد اضافه می‌شود. در مقابل، تعداد دفعات برداشت از کش، تغییری نمی‌کند و تعداد دفعات مراجعات ناموفق نیز افزایش یافت. همچنین تعداد دفعات قرار گرفتن رکورد در کش نیز به میزان یک واحد افزایش یافت زیرا رکورد جدید، از این لحظه به بعد در کش قرار گرفته است.
caching in hibernate
در مرحله آخر نیز، همان رکورد اولیه را این بار در یک session جدید لود می‌کنیم. با توجه به مشترک بودن کش در سطح session ها، درخواست به سمت بانک اطلاعاتی ارسال نشده و رکورد از cache برداشته می‌شود.
caching in hibernate
بنابراین تعداد دفعات استخراج از کش افزایش یافته اما تعداد دفعات مراجعه ناموفق و همچنین تعداد دفعات ذخیره شدن، تغییری نمی‌کند.

ارسال دیدگاه

Captcha 99 − 97 =

در صورت نیاز و یا هر گونه مشکل ایمیل بزنید

پیام با موفقیت ثبت شد.
خطایی رخ داده است.