Class JdbcSagaStore
SagaStore implementation that uses JDBC to store and find Saga instances.
Before using this store make sure the database contains an association value- and saga entry table. These can be
constructed with SagaSqlSchema.sql_createTableAssocValueEntry(Connection) and SagaSqlSchema.sql_createTableSagaEntry(Connection) respectively. For convenience, these tables can be constructed
through the createSchema() operation.
This store manages no transaction of its own. It takes a Connection from the ConnectionProvider it
was given, so its changes commit together with whatever else the surrounding transaction covers. Give it the same
provider instance the transaction manager was given, and use a provider that resolves the connection bound to the
calling thread's transaction on every call, such as SpringDataSourceConnectionProvider. A store holding a
provider that hands out an unbound connection writes outside the transaction entirely.
Such a provider finds the transaction by thread, so the store has to be called on the thread that began it. A
TransactionManager declaring requiresSameThreadInvocations() arranges that, and the ones shipped for
Spring and JPA do. A custom transaction manager that leaves that method at its default of false does not, and
neither does handler code that moves work onto a thread of its own: the provider then finds no transaction and
silently hands out a connection that commits on its own, which survives a rollback of the unit of work.
Because every operation here issues several statements, saga handling should run inside a transaction. Without one each statement commits on its own, so a failure part way through leaves a saga and its associations inconsistent rather than failing cleanly.
The saga type column holds the saga class name and is matched against it. Axon Framework 4 derived both through its
Serializer, which for the default configuration also produced the class name, so an existing table reads and
writes unchanged. An application that mapped its saga classes to some other type name, an XStream alias being the
usual way, has rows this store cannot route to and must rewrite that column to the class name first.
The saga state itself is converted with the configured Converter. Axon Framework 4 defaulted to the
XStreamSerializer unless the application configured another serializer, so the stored state of such an
application is XStream XML, which a JSON-based converter cannot read: loading such a saga fails. Give this store an
XStreamConverter if you are migrating such a scenario to read that state
and to write it back in the same form, which also lets Axon Framework 4 nodes keep handling the same sagas during a
rolling upgrade.
- Since:
- 2.1
- Author:
- Allard Buijze, Kristian Rosenvold
-
Nested Class Summary
Nested ClassesNested classes/interfaces inherited from interface org.axonframework.modelling.saga.repository.SagaStore
SagaStore.Entry<T> -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedJdbcSagaStore(JdbcSagaStore.Builder builder) Instantiate aJdbcSagaStorebased on the fields contained in theJdbcSagaStore.Builder. -
Method Summary
Modifier and TypeMethodDescriptionstatic JdbcSagaStore.Builderbuilder()Instantiate a Builder to be able to create aJdbcSagaStore.voidCreates the SQL Schema required to store Sagas and their associations.voiddeleteSaga(Class<?> sagaType, String sagaIdentifier, Set<AssociationValue> associationValues) Deletes a Saga with givensagaTypeandsagaIdentifierand all its associations.findSagas(Class<?> sagaType, AssociationValue associationValue) Returns identifiers of saga instances of the givensagaTypethat have been associated with the givenassociationValue.voidinsertSaga(Class<?> sagaType, String sagaIdentifier, Object saga, Set<AssociationValue> associationValues) Adds a new Saga and its initial association values to the store.<S> @Nullable SagaStore.Entry<S> voidupdateSaga(Class<?> sagaType, String sagaIdentifier, Object saga, AssociationValues associationValues) Updates a given Saga after its state was modified, applying the association values added and removed since it was last stored.
-
Constructor Details
-
JdbcSagaStore
Instantiate aJdbcSagaStorebased on the fields contained in theJdbcSagaStore.Builder.Will assert that the
ConnectionProvider,SagaSqlSchemaandConverterare notnull, and will throw anAxonConfigurationExceptionif any of them isnull.- Parameters:
builder- theJdbcSagaStore.Builderused to instantiate aJdbcSagaStoreinstance
-
-
Method Details
-
builder
Instantiate a Builder to be able to create aJdbcSagaStore.The
SagaSqlSchemais defaulted to anGenericSagaSqlSchema.The
ConnectionProviderandConverterare hard requirements and as such should be provided.- Returns:
- a Builder to be able to create a
JdbcSagaStore
-
loadSaga
Description copied from interface:SagaStoreLoads a known sagaSagaStore.Entryinstance with givensagaTypeand uniquesagaIdentifier.Due to the concurrent nature of Sagas, it is not unlikely for a Saga to have ceased to exist after it has been found based on associations. Therefore, a repository should return
nullin case a Saga doesn't exists, as opposed to throwing an exception. -
findSagas
Description copied from interface:SagaStoreReturns identifiers of saga instances of the givensagaTypethat have been associated with the givenassociationValue. -
deleteSaga
public void deleteSaga(Class<?> sagaType, String sagaIdentifier, Set<AssociationValue> associationValues) Description copied from interface:SagaStoreDeletes a Saga with givensagaTypeandsagaIdentifierand all its associations. For convenience all known association values are passed along as well, which has the advantage that the saga store is not required to keep an index of association value to saga identifier.- Specified by:
deleteSagain interfaceSagaStore<Object>- Parameters:
sagaType- The type of saga to deletesagaIdentifier- The identifier of the saga to deleteassociationValues- The known associations of the saga
-
updateSaga
public void updateSaga(Class<?> sagaType, String sagaIdentifier, Object saga, AssociationValues associationValues) Description copied from interface:SagaStoreUpdates a given Saga after its state was modified, applying the association values added and removed since it was last stored.- Specified by:
updateSagain interfaceSagaStore<Object>- Parameters:
sagaType- The type of the SagasagaIdentifier- The identifier of the Sagasaga- The Saga instanceassociationValues- The association values of the Saga, carrying the additions and removals to apply
-
insertSaga
public void insertSaga(Class<?> sagaType, String sagaIdentifier, Object saga, Set<AssociationValue> associationValues) Description copied from interface:SagaStoreAdds a new Saga and its initial association values to the store.- Specified by:
insertSagain interfaceSagaStore<Object>- Parameters:
sagaType- The type of the SagasagaIdentifier- The identifier of the Sagasaga- The Saga instanceassociationValues- The initial association values of the Saga
-
createSchema
Creates the SQL Schema required to store Sagas and their associations.- Throws:
SQLException- when an error occurs preparing of executing the required statements
-