Persist aggregates and dispatch events transactionally - domain-driven-design

Could anyone recommend alternatives to 2 phases commits to have the persistence of aggregates happen in the same transaction as the dispatching of related domain events in a non-event-sourced DDD application?
One approach I've tried is to persist the aggregates along with the asynchronous events in the same ACID RDBMS instance, and then have processes poll the events for processing. This works well as long as you don't need several RDBMS instances or non-ACID databases as a write store.

Related

Hazelcast Jet - Support for multiple clients

Can Hazelcast Jet be used for processing of millions of records using multiple clients accessing an event journal and each client would process a portion of the records?
Furthermore, is it possible to accumulate the results processed by different clients?
This is also an architectural question. To fit your aggregation need, you might have clients begin as individual streams, accumulate your aggregates there, then join the streams for common processing. Just as an example.
Also, you do have access to the underlying IMDG technology that you can leverage. You have a free hand at how you want to build the overall architecture.

What is the difference between Akka Persistence and Akka Persistence Query?

Akka persistence query complements Persistence by providing a universal asynchronous stream based query interface that various journal plugins can implement in order to expose their query capabilities.
This is the description of 'Akka Persistence Query' from akka documentation. What I wonder that is it using only for querying, in other words for read-side?
Probably the better question is why isn't Akka persistence query part of Akka persistence? What good is persistence if you can't query it?
Akka persistence seeks to solve one thing and one thing only, make the state of an actor persistent. It doesn't care whether that actor represents a domain entity, or if it's just an operational actor whose state needs to survive restarts (such as is the case for the cluster sharing manager, which used to store its state in Akka persistence before switching to distributed data). It's just a general purpose "make this actors state persistent" feature.
Now, a common use for Akka persistence is to implement event sourced domain entities. Event sourced domain entities however need more than just "make this actor persistent", they usually also need the ability to execute queries across domain entities. And so Akka persistence query exists to allow this, it allows creating cross entity streams that can be processed to populate read side views.
The thing is, not all event stores necessarily make it easy to do cross entity streaming like that. So those that don't can just implement Akka persistence, and be used to make actors persistent, while stores that provide more functionality can also implement Akka persistence query.
This is all greatly simplified, but hopefully explains some of the motivations.
The Akka Persistence Query can be used for querying the journal, and this will be in most of simpler cases sufficient enough.
Nevertheless the main purpose of the Persistence Query is to stream stored events to a specific, or multiple separate, read/query-stores where you will execute your actual queries against.

Understanding when to use stateful services and when to rely on external persistence in Azure Service Fabric

I'm spending my evenings evaluating Azure Service Fabric as a replacement for our current WebApps/CloudServices stack, and feel a little bit unsure about how to decide when services/actors with state should be stateful actors, and when they should be stateless actors with externally persisted state (Azure SQL, Azure Storage and DocumentDB). I know this is a fairly new product (to the general public at least), so there's probably not a lot of best practices in regards to this yet, but I've read through most of the documentation made available by Microsoft without finding a definite answer for this.
The current problem domain I'm approaching is our event store; parts of our applications are based on event sourcing and CQRS, and I'm evaluating how to move this event store over to the Service Fabric platform. The event store is going to contain a lot time series-data, and as it's our only source of truth for the data being persisted there it must be consistent, replicated and stored to some form of durable storage.
One way I have considered doing this is with stateful "EventStream" actor; each instance of an aggregate using event sourcing stores its events within an isolated stream. This means the stateful actor could keep track of all the events for its own stream, and I'd have met my requirements as to how the data is stored (transactional, replicated and durable). However, some streams may grow very large (hundreds of thousands, if not millions, of events), and this is where I'm starting to get unsure. Having an actor with a large amount of state will, I imagine, have impacts on the performance of the system when these large data models needs to be serialized to or deserialized from disk.
Another option is to keep these actors stateless, and have them just read their data from some external storage like Azure SQL - or just go with stateless services instead of actors.
Basically, when is the amount of state for an actor/service "too much" and you should start considering other ways of handling state?
Also, this section in the Service Fabric Actors design pattern: Some anti-patterns documentation leave me a little bit puzzled:
Treat Azure Service Fabric Actors as a transactional system. Azure Service Fabric Actors is not a two phase commit-based system offering ACID. If we do not implement the optional persistence, and the machine the actor is running on dies, its current state will go with it. The actor will be coming up on another node very fast, but unless we have implemented the backing persistence, the state will be gone. However, between leveraging retries, duplicate filtering, and/or idempotent design, you can achieve a high level of reliability and consistency.
What does "if we do not implement the optional persistance" indicate here? I was under the impression that as long as your transaction modifying the state succeeded, your data was persisted to durable storage and replicated to at least a subset of the replicas. This paragraph leaves me wondering if there are situations where state within my actors/services will get lost, and if this is something I need to handle myself. The impression I got from the stateful model in other parts of the documentation seems to counteract this statement.
One option that you have is to keep 'some' of the state in the actor (let's say what could be considered to be hot data that needs to be quickly available) and store everything else on a 'traditional' storage infrastructure such as SQL Azure, DocDB, ....
It is difficult to have a general rule about too much local state but, maybe, it helps to think about hot vs. cold data.
Reliable Actors also offer the ability to customize the StateProvider so you can also consider implementing a customized StateProvider (by implementing the IActorStateProvider) with the specific policies that you need to be more efficient with the requirements that you have in terms of amount of data, latency, reliability and so on (note: documentation is still very minimal on the StateProvider interface but we can publish some sample code if this is something you want to pursue).
About the anti-patterns: the note is more about implementing transactions across multiple actors. Reliable Actors provides full guarantee on reliability of the data within the boundaries of an actor. Because of the distributed and loosly coupled nature of the Actor model, implementing transactions that involve multiple actors is not a trivial task. If 'distributed' transactions is a strong requirement, the Reliable Services programming model is probably a better fit.
I know this has been answered, but recently found myself in the same predicament with a CQRS/ES system and here's how I went about it:
Each Aggregate was an actor with only the current state stored in it.
On a command, the aggregate would effect a state change and raise an event.
Events themselves were stored in a DocDb.
On activation, AggregateActor instances read events from DocDb if available to recreate its state. This is obviously only performed once per actor activation. This took care of the case where an actor instance is migrated from one node to another.
To answer #Trond's sedcondary question which is, "What does, 'if we do not implement the optional persistance' indicate here?"
An actor is always a stateful service, and its state can be configured, using an attribute on the actor class, to operate in one of three modes:
Persisted. The state is replicated to all replica instances, and it
also written to disk. This the state is maintained even if all
replicas are shut down.
Volatile. The state is replicated to all
replica instances, in memory only. This means as long as one replica
instance is alive the state is maintained. But when all replicas are
shut down the state is lost and cannot be recovered after they are
restarted.
No persistence. The state is not replicated to other
replica instances, nor to disk. This provides the least state
protection.
A full discussion of the topic can be found in the Microsoft documentation

does Hibernate work with akka actor?

my main concern is on ThreadLocal.
akka actors don't bind to specific thread, so any use of thread local storage will be problematic on akka actors
does Hibernate use ThreadLocal?
can they coexist in this case?
Yes. I use Hibernate (via the JPA interface) together with Akka actors.
I have two approaches to deal with multi-threading:
If each actor updates information that cannot conflict with other actors (for example, each row in a table will never be used by multiple actors), you can create a single entity manager per actor and use that for the life of the actor. Although, if a transaction fails it may be best to discard the entity manager.
Otherwise, in each invocation of the actor (via it's receive function) that needs database access, create a new entity manager, begin a transaction, access the database, commit the transaction, and then close the entity manager.
I have the first approach running in production systems.

CQRS/ES - changing two aggregates

I’ve got problem with DDD. I just started using it so I don’t have a lot of experience.
There are two bounded contexts: Maintenance and Clients. Each Client has list of parts of an engine. In Maintenance are stored Companies whose occupation is repairs. Clients may choose preferred company to each part.
Administrator can suspend the company. There are changes in two aggregates. At the first, it change company status and next company should be removed from clients who prefer it.
What is the best pattern to deal with it?
I can create two handlers in aggregates but how I rollback changes when one of handlers throw exception?
It's looks like you need to revise your consistency boundaries in aggregates.
But if after revising you still need to change two aggregates in one transaction you can think about eventually consistent system and use domain events (but in CQRS you already do this, isn't it?).
Vaughn Vernon in his book "Implementing Domain-Driven Design" suggest next method for working with eventual consistency:
aggregate publish domain event which is delivered to one or more subscribers. Each subscriber is executed in it's own transaction (so you still change one aggregate in transaction). If transaction fails (subscriber don't acknowledge success in timeout time) aggregate send message again or execute some rollback routines.
Since you are using Event Sourcing you can mark "failed" event as rejected and use Fowler's Retroactive Event mechanism.

Resources