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.voidEnd any active session on the lock subspace by releasing the lock no matter whether this session holds the lock or not.static voidendAnySession(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.voidUpdate 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 thesessionIdis 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
nullwhen 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
nullwhen 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
nullwhen 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:
trueif 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
-