DATAMONGO-1920 - Polishing.
Slightly tweak method names. Document MongoDatabaseUtils usage in the context of MongoTransactionManager. Rename SessionSynchronization constants to align with AbstractPlatformTransactionManager. Slightly tweak Javadoc and reference docs for typos. Original pull request: #554.
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
[[mongo.sessions]]
|
||||
= MongoDB Sessions
|
||||
|
||||
As of version 3.6 MongoDB supports a concept of Sessions. The use of sessions enables MongoDBs https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/#causal-consistency[Causal Consistency] model guaranteeing to execute operations in an order that respect their causal relationships. Those are split into ``ServerSession``s and ``ClientSession``s. In the following when we speak of session we refer to `ClientSession`.
|
||||
As of version 3.6, MongoDB supports a concept of Sessions. The use of sessions enables MongoDB's https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/#causal-consistency[Causal Consistency] model guaranteeing to execute operations in an order that respect their causal relationships. Those are split into ``ServerSession``s and ``ClientSession``s. In the following when we speak of session, we refer to `ClientSession`.
|
||||
|
||||
WARNING: Operations within a client session are not isolated from operations outside the session.
|
||||
|
||||
Both `MongoOperations` and `ReactiveMongoOperations` provide gateway methods for tying a `ClientSession` to the operations themselves. `MongoCollection` and `MongoDatabase` use session proxy objects implementing MongoDB's collection and and database interfaces so there's no need to add a session on each call. This means that a potential call to `MongoCollection#find()` is delegated to `MongoCollection#find(ClientSession)`.
|
||||
Both `MongoOperations` and `ReactiveMongoOperations` provide gateway methods for tying a `ClientSession` to the operations themselves. `MongoCollection` and `MongoDatabase` use session proxy objects implementing MongoDB's collection and database interfaces, so there's no need to add a session on each call. This means that a potential call to `MongoCollection#find()` is delegated to `MongoCollection#find(ClientSession)`.
|
||||
|
||||
NOTE: Methods like `(Reactive)MongoOperations#getCollection` returning native MongoDB Java Driver gateway objects, such as `MongoCollection`, that themselves offer dedicated methods for `ClientSession` are *NOT* be session-proxied. So make sure to provide the `ClientSession` where needed when interacting directly with a `MongoCollection` or `MongoDatabase` and not via one of the `#execute` callbacks on `MongoOperations`.
|
||||
|
||||
.ClientSession with `MongoOperations`
|
||||
Let's take a look at a simple session example:
|
||||
|
||||
.`ClientSession` with `MongoOperations`
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@@ -42,7 +44,7 @@ session.close() <4>
|
||||
|
||||
WARNING: When dealing with ``DBRef``s, especially lazily loaded ones, it is essential to **not** close the `ClientSession` before all data is loaded. Otherwise, lazy fetch fails.
|
||||
|
||||
The reactive counterpart uses the very same building blocks as the imperative one.
|
||||
The reactive counterpart uses the very same building blocks as the imperative one:
|
||||
|
||||
.ClientSession with `ReactiveMongoOperations`
|
||||
====
|
||||
@@ -74,19 +76,20 @@ template.withSession(session)
|
||||
<3> Make sure to close the `ClientSession`.
|
||||
====
|
||||
|
||||
By using a `Publisher` providing the actual session you can defer session acquisition to the point of actual subscription.
|
||||
Still you need to close the session when done in order to not pollute the server with stale sessions. Use the `doFinally` hook on `execute` to call `ClientSession#close()` when you don't need the session any more.
|
||||
By using a `Publisher` providing the actual session, you can defer session acquisition to the point of actual subscription.
|
||||
Still, you need to close the session when done to not pollute the server with stale sessions. Use the `doFinally` hook on `execute` to call `ClientSession#close()` when you don't need the session anymore.
|
||||
In case you prefer having more control over the session itself, you can always obtain the `ClientSession` via the driver and provide it via a `Supplier`.
|
||||
|
||||
|
||||
[[mongo.transactions]]
|
||||
= MongoDB Transactions
|
||||
|
||||
As of version 4 MongoDB supports https://www.mongodb.com/transactions[Transactions]. Transactions are built on top of <<mongo.sessions,Sessions>> and therefore require an active `ClientSession`.
|
||||
As of version 4, MongoDB supports https://www.mongodb.com/transactions[Transactions]. Transactions are built on top of <<mongo.sessions,Sessions>> and therefore require an active `ClientSession`.
|
||||
|
||||
NOTE: By default, unless you specify a `MongoTransactionManager` within your application context, transaction support is **DISABLED**. You may use `setSessionSynchronization(ANY)` to participate in ongoing non native MongoDB transactions.
|
||||
NOTE: Unless you specify a `MongoTransactionManager` within your application context, transaction support is **DISABLED**. You may use `setSessionSynchronization(ALWAYS)` to participate in ongoing non-native MongoDB transactions.
|
||||
|
||||
To get full programmatic control over transactions you may want to use the session callback on `MongoOperations`.
|
||||
To get full programmatic control over transactions, you may want to use the session callback on `MongoOperations`.
|
||||
|
||||
An example of programmatic transaction control within a `SessionCallback` is shown below:
|
||||
|
||||
.Programmatic transactions
|
||||
====
|
||||
@@ -123,16 +126,16 @@ template.withSession(session)
|
||||
<5> Do not forget to close the session when done.
|
||||
====
|
||||
|
||||
The above example allows you to have full control over transactional behavior while using the session scoped `MongoOperations` instance within the callback to ensure the session is passed on to each and every server call.
|
||||
The above example allows you to have full control over transactional behavior while using the session scoped `MongoOperations` instance within the callback to ensure the session is passed on to every server call.
|
||||
To avoid some of the overhead that comes with this approach usage of a `TransactionTemplate` can take away some of the noise of manual transaction flow.
|
||||
|
||||
== Transactions with TransactionTemplate
|
||||
== Transactions with `TransactionTemplate`
|
||||
|
||||
.Transactions with TransactionTemplate
|
||||
.Transactions with `TransactionTemplate`
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
template.setSessionSynchronization(ANY); <1>
|
||||
template.setSessionSynchronization(ALWAYS); <1>
|
||||
|
||||
// ...
|
||||
|
||||
@@ -152,17 +155,17 @@ txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
};
|
||||
});
|
||||
----
|
||||
<1> Manually enable transaction synchronization.
|
||||
<1> Enable transaction synchronization during Template API configuration. Changing state of `MongoTemplate` during runtime can cause threading/visibility issues.
|
||||
<2> Create the `TransactionTemplate` using the provided `PlatformTransactionManager`.
|
||||
<3> Within the callback the `ClientSession` and transaction are already registered.
|
||||
====
|
||||
|
||||
== Transactions with MongoTransactionManager
|
||||
== Transactions with `MongoTransactionManager`
|
||||
|
||||
`MongoTransactionManager` is the gateway to the well known Spring transaction support. It allows applications to use http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/html/transaction.html[managed transaction features of Spring].
|
||||
The `MongoTransactionManager` binds a `ClientSession` to the thread. `MongoTemplate` automatically detects those and operates on them accordingly. `MongoTemplate` can also participate in other, ongoing transactions.
|
||||
The `MongoTransactionManager` binds a `ClientSession` to the thread. `MongoTemplate` detects those and operates on these resources which are associated with the transaction accordingly. `MongoTemplate` can also participate in other, ongoing transactions.
|
||||
|
||||
.Transactions with MongoTransactionManager
|
||||
.Transactions with `MongoTransactionManager`
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@@ -196,5 +199,5 @@ public class StateService {
|
||||
<2> Mark methods as transactional.
|
||||
====
|
||||
|
||||
NOTE: `@Transactional(readOnly = true)` advises the `MongoTransactionManager` to also start a transaction adding the
|
||||
`ClientSession` to outgoing requests.
|
||||
NOTE: `@Transactional(readOnly = true)` advises `MongoTransactionManager` also to start a transaction adding the
|
||||
`ClientSession` to outgoing requests.
|
||||
|
||||
Reference in New Issue
Block a user