Wprowadzenie
Pamięć podręczna umożliwia wielokrotne wykorzystywanie złożonych wyników obliczeń bez konieczności ich ponownego obliczania za każdym razem. Jeśli dane, na których oparte są obliczenia, ulegną zmianie, pamięć podręczna musi odrzucić nieaktualną zawartość.
System zapewnia interfejs umożliwiający łatwe tworzenie pamięci podręcznych. Interfejs ten automatycznie odrzuca nieaktualną zawartość pamięci podręcznej.
Grupa docelowa
- Programiści
- Konsultanci techniczni
Opis
Silnik systemu zapewnia interfejs dla pamięci podręcznych w PGM. Instancje pamięci podręcznych zarejestrowanych za pośrednictwem tego interfejsu mogą być odpytywane przez CisSystemManager. Instancje pamięci podręcznej są generowane przez silnik systemowy za pośrednictwem CisFactory.
Wszystkie obiekty biznesowe, na podstawie których obliczana jest zawartość pamięci podręcznej, muszą być zatem określone dla każdej pamięci podręcznej. Jeśli obiekt biznesowy w bazie danych OLTP zostanie zmieniony, wszystkie pamięci podręczne w tym OLTP, które używają tego obiektu biznesowego, zostaną całkowicie unieważnione. Podczas unieważniania odwołanie do przestarzałej instancji pamięci podręcznej jest odrzucane, a nowa instancja jest tworzona przy następnym zapytaniu o instancję pamięci podręcznej. Przestarzała instancja pamięci podręcznej nie jest zatem powiadamiana o tym, że jest przestarzała, ale tworzona jest nowa instancja pamięci podręcznej, która działa na bieżących danych.
Aby uzyskać bieżącą instancję pamięci podręcznej, musi ona być ponownie odpytywana przez menagera za każdym razem, gdy jest używana.
Implementacja pamięci podręcznej
Interfejs wymaga jedynie, aby klasa implementująca pamięć podręczną mogła zostać utworzona za pomocą CisFactory.createInstance
. Oznacza to, że musi ona posiadać konstruktor bez parametrów. Chociaż nie ma wspólnej klasy bazowej ani interfejsu dla pamięci podręcznych, należy przestrzegać konwencji programowania.
Zmienne specyficzne dla sesji
Pamięć podręczna nie może przechowywać żadnych zmiennych i managerów specyficznych dla sesji. Pamięć podręczna jest używana we wszystkich sesjach. W szczególności niedozwolone jest, aby pamięć podręczna posiadała zmienne instancji następujących klas:
- – CisEnvironment
- – CisObjectManager
- – CisTransactionManager
- – CisMessageManager
- …
Wszystkie powyższe Manager muszą być ponownie odpytywane w każdej metodzie. Jeśli Manager jest używany w sesji innej niż ta, w której zostały utworzone, mogą wystąpić błędy.
Właściwości specyficzne dla sesji
Pamięć podręczna musi uwzględniać fakt, że w każdej sesji obowiązuje inny język treści lub inny kontekst organizacyjny.
Jeśli na przykład język treści nie jest brany pod uwagę w pamięci podręcznej, język treści pierwszej sesji, która żąda wartości specyficznej dla języka z pamięci podręcznej, określa tłumaczenie, w którym ta wartość jest wydawana wszystkim innym sesjom.
Pomocne może być zapisanie tylko klucza głównego (GUID) obiektu biznesowego w pamięci podręcznej i załadowanie tego obiektu biznesowego za pomocą getObject podczas odpytywania. Ma to następujące zalety:
- język treści obiektu biznesowego jest określany przez bieżącą sesję
- jeśli obiekt biznesowy jest zależny od czasu, dostarczana jest aktualnie obowiązująca wersja
- zapotrzebowanie na pamięć podręczną jest niskie, jeśli w pamięci podręcznej przechowywane są tylko identyfikatory GUID
- dostęp do obiektów biznesowych za pośrednictwem klucza głównego jest bardzo szybki.
Wymagania dotyczące pamięci
Każda pamięć podręczna może zajmować tylko ograniczoną ilość pamięci głównej. Nie ma potrzeby, aby pamięć podręczna zajmowała nieograniczoną ilość pamięci, w zależności od konstelacji danych, ponieważ wpływa to na działanie serwera aplikacji.
Dlatego do przechowywania danych pamięci podręcznej należy zawsze używać kontenerów o ograniczonym rozmiarze. Na przykład klasy CisLRUMap i LRUMap to mapy o ograniczonym rozmiarze, w których po osiągnięciu maksymalnego rozmiaru element, który nie był używany przez najdłuższy czas, jest usuwany po wstawieniu nowego elementu.
Synchronizacja
Dowolna liczba sesji może uzyskać dostęp do tej samej instancji pamięci podręcznej w tym samym czasie. Należy zatem zsynchronizować metody dostępu, zwłaszcza w przypadku korzystania z map LRU.
Rejestracja
Pamięci podręczne dla bazy danych OLTP są rejestrowane za pomocą haka com.cisag.pgm.appserver.hook.CacheRegistryHook
z definicji umowy haka com.cisag.pgm.appserver.Server
. Dla każdej pamięci podręcznej należy wywołać metodę registerOLTPCache
w CacheRegistry
z klasą pamięci podręcznej, opcjonalnie z dodatkowym identyfikatorem i klasami obiektów biznesowych używanych przez pamięć podręczną. ID zapewnia dodatkową identyfikację oprócz klasy. Kilka pamięci podręcznych z tą samą klasą pamięci podręcznej może być zarejestrowanych z różnymi identyfikatorami.
Rejestracja pamięci podręcznej CalendarLogic
dla obiektów biznesowych Calendar, CalendarDayTypes i DayType:
registry.registerOLTPCache( com.cisag.app.general.log.CalendarLogic.class, com.cisag.app.general.obj.Calendar.class, com.cisag.app.general.obj.CalendarDayTypes.class, com.cisag.app.general.obj.DayType.class); Rejestracja pamięci podręcznej TaxExemptions z identyfikatorem "1" dla obiektu biznesowego TaxExemption: registry.registerOLTPCache( com.cisag.app.financials.log.TaxExemptions.Cache.class, "1", com.cisag.app.financials.obj.TaxExemption.class);
Pobieranie instancji pamięci podręcznej
Wystąpienie pamięci podręcznej może być odpytywane przez menedżera systemu przy użyciu następujących metod
<T> T getCacheInstance(Class<T> cacheClass);
<T> T getCacheInstance(Class<T> cacheClass, String cacheId);
Metody te zwracają istniejącą i prawidłową instancję pamięci podręcznej lub tworzona jest nowa instancja.
Instancję pamięci podręcznej można odrzucić w Menedżerze systemu za pomocą następujących metod:
<T> void invalidateCacheInstance(Class<T> cacheClass);
<T> void invalidateCacheInstance(Class<T> cacheClass,
String cacheId);
Wyraźne unieważnienie instancji pamięci podręcznej ma sens, jeśli w instancji pamięci podręcznej zarządzane są dane, które nie pochodzą z obiektów biznesowych, a zatem nie mogą być monitorowane przez usługę trwałości.
Przykład
public class InfoLogic { private LRUMap<CisInfo> cache; protected InfoLogic() { cache = new LRUMap<CisInfo>(CACHE_SIZE); } public static InfoLogic getInstance() { return CisEnvironment.getInstance().getSystemManager(). getCacheInstance(InfoLogic.class); } public CisInfo getInfo(String name) { CisEnvironment env = CisEnvironment.getInstance(); // wyszukiwanie w pamięci podręcznej CisKey key = CisKey.create(name, env.getDisplayLanguage(), env.getContentLanguage()); CisInfo result; synchronized (cache) { result = cache.get(key); } if (result!=null) { return result; } // utworzenie nowej informacji ... // umieszczenie informacji w pamięci podręcznej synchronized (cache) { cache.put(key,result); } return result; } }