You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/StreamCacheRealmProvider.java
+29-20Lines changed: 29 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -66,8 +66,6 @@
66
66
* it is added to the cache. So, we keep the version number around for this.
67
67
* - In a transaction, objects are registered to be invalidated. If an object is marked for invalidation within a transaction
68
68
* a cached object should never be returned. An DB adapter should always be returned.
69
-
* - At prepare phase of the transaction, a local lock on the revision cache will be obtained for each object marked for invalidation
70
-
* we sort the list of these keys to order local acquisition and avoid deadlocks.
71
69
* - After DB commits, the objects marked for invalidation are invalidated, or rather removed from the cache. At this time
72
70
* the revision cache entry for this object has its version number bumped.
73
71
* - Whenever an object is marked for invalidation, the cache is also searched for any objects that are related to this object
@@ -88,15 +86,20 @@
88
86
* - There is a Infinispan @Listener registered. If an invalidation event happens, this is treated like
89
87
* the object was removed from the database and will perform evictions based on that assumption.
90
88
* - Eviction events will also cascade other evictions, but not assume this is a db removal.
89
+
* - With an invalidation cache, if you remove an entry on node 1 and this entry does not exist on node 2, node 2 will not receive a @Listener invalidation event.
90
+
* so, hat we have to put a marker entry in the invalidation cache before we read from the DB, so if the DB changes in between reading and adding a cache entry, the cache will be notified and bump
91
+
* the version information.
92
+
*
93
+
* DBs with Repeatable Read:
94
+
* - DBs like MySQL are Repeatable Read by default. So, if you query a Client for instance, it will always return the same result in the same transaction even if the DB
95
+
* was updated in between these queries. This makes it possible to store stale cache entries. To avoid this problem, this class stores the current local version counter
96
+
* at the beginningof the transaction. Whenever an entry is added to the cache, the current coutner is compared against the counter at the beginning of the tx. If the current
97
+
* is greater, then don't cache.
91
98
*
92
99
* Groups and Roles:
93
100
* - roles are tricky because of composites. Composite lists are cached too. So, when a role is removed
94
101
* we also iterate and invalidate any role or group that contains that role being removed.
95
102
*
96
-
* - Clustering gotchyas. With an invalidation cache, if you remove an entry on node 1 and this entry does not exist on node 2, node 2 will not receive a @Listener invalidation event.
97
-
* so, hat we have to put a marker entry in the invalidation cache before we read from the DB, so if the DB changes in between reading and adding a cache entry, the cache will be notified and bump
98
-
* the version information.
99
-
*
100
103
* - any relationship should be resolved from session.realms(). For example if JPA.getClientByClientId() is invoked,
101
104
* JPA should find the id of the client and then call session.realms().getClientById(). THis is to ensure that the cached
102
105
* object is invoked and all proper invalidation are being invoked.
@@ -124,14 +127,20 @@ public class StreamCacheRealmProvider implements CacheRealmProvider {
if (id.endsWith("realm.clients")) logger.trace("addRevisioned rev2 == null realm.clients");
146
145
return;
147
146
}
148
-
if (rev > session.getTransaction().getStartupRevision()) { // revision is ahead transaction start. Other transaction updated in the meantime. Don't cache
147
+
if (rev > startupRevision) { // revision is ahead transaction start. Other transaction updated in the meantime. Don't cache
0 commit comments