Class SynchronizedSession
SynchronizedSession
is a concept introduced to avoid multiple attempts at performing the same operation
(with each attempt opening multiple transactions running concurrently and/or consecutively) from running concurrently
and contending for resources. Each attempt corresponds to a session identified by a session ID. Of the sessions with
the same lock subspace, only the one holding the lock is allowed to work.
Each session should and should only try to acquire the lock when the session is initialized.
When a session holds the lock, it is protected from other sessions grabbing the same lock for an extended length of
time (a.k.a lease). Another new session can only take lock if the lease of the original lock owner is outdated. (Note
a session is allowed to work even if its lease is outdated, as long as no other session takes its lock.) In order to
keep the lease, every time a session is used, it needs to update the lease's end time to some time (configured by
leaseLengthMillis
) later than current time. (The lease time is used only as an optimization.
SynchronizedSession
does not depend on synchronized clocks for the correctness of mutual exclusion.)
If a session is not able to acquire the lock during the initialization or loses the lock later, it will get a
SynchronizedSessionLockedException
. The session is considered ended when it gets a such exception. It can
neither try to acquire the lock again nor commit any work.
initializeSessionAsync(com.apple.foundationdb.Transaction)
should be used when initializing a session to acquire the lock, while
checkLockAsync(Transaction)
and updateLockSessionLeaseEndTime(Transaction)
should be used in every
other transactions to check the lock and keep the lease. Please refer to SynchronizedSessionRunner
in
fdb-record-layer-core
for an example of using SynchronizedSession
in practice.
-
Constructor Summary
ConstructorsConstructorDescriptionSynchronizedSession
(Subspace lockSubspace, UUID sessionId, long leaseLengthMillis) Construct a session. -
Method Summary
Modifier and TypeMethodDescriptionstatic CompletableFuture<Boolean>
checkActiveSessionExists
(Transaction tr, Subspace lockSubspace) Check if there is any active session on the given lock subspace, so that a new session would not able to be initialized.Check if the session still holds the lock.void
End any active session on the lock subspace by releasing the lock no matter whether this session holds the lock or not.static void
endAnySession
(Transaction tr, Subspace lockSubspace) End any active session on the given lock subspace by releasing the lock.Get session ID.Initialize the session by acquiring the lock.End the session by releasing the lock if it still holds the lock.void
Update the lease's end time.
-
Constructor Details
-
SynchronizedSession
public SynchronizedSession(@Nonnull Subspace lockSubspace, @Nonnull UUID sessionId, long leaseLengthMillis) Construct a session. Remember to callinitializeSessionAsync(Transaction)
if thesessionId
is newly generated.- Parameters:
lockSubspace
- the lock for which this session contendssessionId
- session IDleaseLengthMillis
- length between last access and lease's end time in milliseconds
-
-
Method Details
-
initializeSessionAsync
Initialize the session by acquiring the lock. This should be invoked before a new session is ever used.- Parameters:
tr
- transaction to use- Returns:
- a future that will return
null
when the session is initialized
-
getSessionId
Get session ID.- Returns:
- session ID
-
checkLockAsync
Check if the session still holds the lock. This should be invoked in every transaction in the session to follow the contract.- Parameters:
tr
- transaction to use- Returns:
- a future that will return
null
when the lock is checked
-
releaseLock
End the session by releasing the lock if it still holds the lock. Do nothing otherwise.- Parameters:
tr
- transaction to use- Returns:
- a future that will return
null
when the lock is no longer this session
-
endAnySession
End any active session on the lock subspace by releasing the lock no matter whether this session holds the lock or not.It only takes place when the given transaction is committed. It will only be enforced when the other processes holding the lock go to check the lease in later transactions, where they will fail with
SynchronizedSessionLockedException
.- Parameters:
tr
- transaction to use
-
endAnySession
End any active session on the given lock subspace by releasing the lock.It only takes place when the given transaction is committed. It will only be enforced when the other processes holding the lock go to check the lease in later transactions, where they will fail with
SynchronizedSessionLockedException
.- Parameters:
tr
- transaction to uselockSubspace
- the lock whose active session needs to be ended
-
checkActiveSessionExists
public static CompletableFuture<Boolean> checkActiveSessionExists(@Nonnull Transaction tr, @Nonnull Subspace lockSubspace) Check if there is any active session on the given lock subspace, so that a new session would not able to be initialized.- Parameters:
tr
- transaction to uselockSubspace
- the lock whose active session needs to be checked- Returns:
true
if there is any active session, otherwisefalse
-
updateLockSessionLeaseEndTime
Update the lease's end time. This should be invoked in every transaction in the session to keep the session alive.- Parameters:
tr
- transaction to use
-