sql >> Databáze >  >> RDS >> PostgreSQL

Jak aktualizovat entity JPA, když se backendová databáze mění asynchronně?

Doporučuji přidat @Startup @Singleton třída, která naváže připojení JDBC k databázi PostgreSQL a používá LISTEN a NOTIFY ke zpracování neplatnosti mezipaměti.

Aktualizovat :Zde je další zajímavý přístup, pomocí pgq a kolekce pracovníků pro zneplatnění.

Signalizace zneplatnění

Přidejte na tabulku, která se aktualizuje, spouštěč, který odešle NOTIFY kdykoli je entita aktualizována. Na PostgreSQL 9.0 a vyšší toto NOTIFY může obsahovat užitečné zatížení, obvykle ID řádku, takže nemusíte zneplatnit celou mezipaměť, pouze entitu, která se změnila. Ve starších verzích, kde není užitečné zatížení podporováno, můžete buď přidat neplatné položky do tabulky protokolu s časovým razítkem, kterou se vaše pomocná třída dotazuje, když dostane NOTIFY nebo rovnou zneplatnit celou mezipaměť.

Vaše pomocná třída nyní LISTEN s na NOTIFY události, které trigger odešle. Když dostane NOTIFY může zneplatnit jednotlivé položky cache (viz níže) nebo vyprázdnit celou cache. Můžete poslouchat oznámení z databáze s podporou naslouchání/upozorňování PgJDBC. Budete muset rozbalit jakýkoli fond připojení spravovaný java.sql.Connection abyste se dostali k základní implementaci PostgreSQL, abyste ji mohli přenést do org.postgresql.PGConnection a zavolejte getNotifications() na to.

Alternativa k LISTEN a NOTIFY , můžete dotazovat tabulku protokolu změn na časovači a mít spouštěč v tabulce problémů připojovat změněná ID řádků a měnit časová razítka do tabulky protokolu změn. Tento přístup bude přenosný s výjimkou potřeby jiného spouštěče pro každý typ DB, ale je neefektivní a méně aktuální. Bude to vyžadovat časté neefektivní dotazování a stále bude mít časové zpoždění, které přístup naslouchání/upozorňování nezaznamená. V PostgreSQL můžete použít UNLOGGED tabulky, aby se trochu snížily náklady na tento přístup.

Úrovně mezipaměti

EclipseLink/JPA má několik úrovní ukládání do mezipaměti.

Mezipaměť 1. úrovně je v EntityManager úroveň. Pokud je entita připojena k EntityManager od persist(...) , merge(...) , find(...) , atd., pak EntityManager je nutné vrátit stejnou instanci této entity při opětovném přístupu v rámci stejné relace, bez ohledu na to, zda na něj vaše aplikace stále odkazuje. Tato připojená instance nebude aktuální, pokud se obsah vaší databáze mezitím změnil.

Mezipaměť 2. úrovně, která je volitelná, se nachází v EntityManagerFactory úroveň a je tradičnější cache. Není jasné, zda máte povolenou mezipaměť 2. úrovně. Zkontrolujte své protokoly EclipseLink a persistence.xml . Přístup k mezipaměti 2. úrovně můžete získat pomocí EntityManagerFactory.getCache(); viz Cache .

@thedayofcondor ukázal, jak vyprázdnit mezipaměť 2. úrovně pomocí:

em.getEntityManagerFactory().getCache().evictAll();

ale můžete také vystěhovat jednotlivé objekty pomocí evict(java.lang.Class cls, java.lang.Object primaryKey) zavolejte:

em.getEntityManagerFactory().getCache().evict(theClass, thePrimaryKey);

který můžete použít ze svého @Startup @Singleton NOTIFY listener zrušit platnost pouze těch položek, které se změnily.

Mezipaměť 1. úrovně není tak snadná, protože je součástí vaší aplikační logiky. Budete chtít zjistit, jak funguje EntityManager , připojené a oddělené entity atd. Jednou z možností je vždy použít oddělené entity pro danou tabulku, kde použijete nový EntityManager kdykoli získáte entitu. Tato otázka:

Zrušení relace EntityManager JPA

má užitečnou diskuzi o manipulaci se zneplatněním mezipaměti správce entity. Je však nepravděpodobné, že by šlo o EntityManager cache je váš problém, protože webová služba RESTful je obvykle implementována pomocí krátkého EntityManager sezení. To bude pravděpodobně problém pouze v případě, že používáte kontexty rozšířené perzistence nebo pokud vytváříte a spravujete svůj vlastní EntityManager relací namísto použití persistence spravované kontejnerem.



  1. Limit velikosti datového typu JSON v PostgreSQL

  2. Metoda sběru:Postup DELETE v databázi Oracle

  3. 6 způsobů, jak zkontrolovat, zda existuje tabulka na serveru SQL (příklady T-SQL)

  4. Příklady ADDTIME() – MySQL