Exloring Lightweight Event Sourcing - Scala Days 2011
-
Upload
erik-rozendaal -
Category
Technology
-
view
6.292 -
download
1
description
Transcript of Exloring Lightweight Event Sourcing - Scala Days 2011
![Page 2: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/2.jpg)
Exploring lightweight event sourcing
Goals
• Understand event sourcing
• Show why Scala is well-suited as implementation language
2
![Page 3: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/3.jpg)
Exploring lightweight event sourcing
Event Sourcing
• Documented by Martin Fowler at http://martinfowler.com/eaaDev/EventSourcing.html (2005)
• Made practical by Greg Young (QCon 2008)
• Applied to complex, high volume systems (financial trading)
• But what about small systems?
3
![Page 4: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/4.jpg)
Exploring lightweight event sourcing
• Domain-Driven Design An approach to software development that suggests that (1) For most software projects, the primary focus should be on the domain and domain logic; and (2) Complex domain designs should be based on a model.
• Domain Expert A member of a software project whose field is the domain of the application, rather than software development. Not just any user of the software, the domain expert has deep knowledge of the subject.
• Ubiquitous Language A language structured around the domain model and used by all team members to connect all the activities of the team with the software.
4
![Page 5: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/5.jpg)
Exploring lightweight event sourcing
Durability
5
![Page 6: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/6.jpg)
Exploring lightweight event sourcing
Durability
• Most applications require durability of data
5
![Page 7: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/7.jpg)
Exploring lightweight event sourcing
Durability
• Most applications require durability of data
• UPDATE invoice WHERE id = 1234 SET total_amount = 230
5
![Page 8: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/8.jpg)
Exploring lightweight event sourcing
Durability
• Most applications require durability of data
• UPDATE invoice WHERE id = 1234 SET total_amount = 230
• What happened to previous order amount?
5
![Page 9: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/9.jpg)
Exploring lightweight event sourcing
Durability
• Most applications require durability of data
• UPDATE invoice WHERE id = 1234 SET total_amount = 230
• What happened to previous order amount?
• What was the reason for the change?
5
![Page 10: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/10.jpg)
Exploring lightweight event sourcing
ORMs
• Query and persist current state in DB
• Tightly couples domain and data model
• Leaky abstraction
• Still “lossy” and the intent of the user is not captured
6
![Page 11: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/11.jpg)
Exploring lightweight event sourcing
Behavior?
7
![Page 12: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/12.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00
Behavior?
7
![Page 13: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/13.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Behavior?
7
![Page 14: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/14.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Behavior?
7
![Page 15: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/15.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
It’s just data mutation
8
![Page 16: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/16.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
It’s just data mutation
8
![Page 17: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/17.jpg)
Exploring lightweight event sourcing
“Inexperienced programmers love magic because it saves their time. Experienced programmers hate magic because it wastes their time.” – @natpryce
9
ORM implementation
![Page 18: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/18.jpg)
Exploring lightweight event sourcing
Event Sourcing
10
• All state changes are explicitly captured using domain events
• Events represent the outcome of behavior
• Capture the intent of the user and the related data
• The domain expert understands and can explain the meaning of the domain events
![Page 19: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/19.jpg)
Exploring lightweight event sourcing
Domain Behavior
11
![Page 20: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/20.jpg)
Exploring lightweight event sourcing
Draft Invoice Created
create
Domain Behavior
11
![Page 21: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/21.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00
Draft Invoice Created
create
apply
Domain Behavior
11
![Page 22: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/22.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
create
createapply
Domain Behavior
11
![Page 23: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/23.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
create
createapply apply
Domain Behavior
11
![Page 24: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/24.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
Item: "Food"Item amount: 9.95Total amount: 9.95
Invoice Item Added
create
create createapply apply
Domain Behavior
11
![Page 25: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/25.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
Item: "Food"Item amount: 9.95Total amount: 9.95
Invoice Item Added
create
create createapply apply apply
Domain Behavior
11
![Page 26: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/26.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
Item: "Food"Item amount: 9.95Total amount: 9.95
Invoice Item Added
Only the events are stored on disk
12
![Page 27: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/27.jpg)
Exploring lightweight event sourcing
Reloading from history
13
![Page 28: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/28.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00
Draft Invoice Created
apply
Reloading from history
13
![Page 29: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/29.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
apply apply
Reloading from history
13
![Page 30: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/30.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
Item: "Food"Item amount: 9.95Total amount: 9.95
Invoice Item Added
apply apply apply
Reloading from history
13
![Page 31: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/31.jpg)
Exploring lightweight event sourcing
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
Invoice
Status: "Draft"
Total: 0.00 Invoice
Status: "Draft"
Recipient: "Erik"
Total: 0.00
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
Item: "Food"Item amount: 9.95Total amount: 9.95
Invoice Item Added
apply apply apply
Reloading from history
13
![Page 32: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/32.jpg)
Exploring lightweight event sourcing
Aggregates
• A cluster of associated objects that are treated as a unit for the purpose of data changes
• Each aggregate has its own stream of events
• Consistency boundary
14
![Page 33: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/33.jpg)
Exploring lightweight event sourcing
Aggregates
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
15
![Page 34: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/34.jpg)
Exploring lightweight event sourcing
Aggregates
Invoice
Status: "Draft"
Recipient: "Erik"
Invoice Item
Total: 9.95
Item: "Food"
Amount: 9.95
15
Draft Invoice Created
Recipient: "Erik"
Invoice Recipient Changed
Item: "Food"Item amount: 9.95Total amount: 9.95
Invoice Item Added
![Page 35: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/35.jpg)
Exploring lightweight event sourcing
Event Store
16
• Stores sequence of events per aggregate
• Dispatches events when successfully committed
• Replays events on startup
• It’s your application’s transaction log
![Page 36: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/36.jpg)
Exploring lightweight event sourcing
Event Store
• No good for queries!
• Use separate views or reports that use the domain events to capture answers to queries
17
![Page 37: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/37.jpg)
Exploring lightweight event sourcing
Domain Code
18
sealed trait InvoiceEventcase class InvoiceCreated() extends InvoiceEventcase class InvoiceRecipientChanged(recipient: String) extends InvoiceEventcase class InvoiceItemAdded(item: InvoiceItem, totalAmount: BigDecimal) extends InvoiceEventcase class InvoiceSent(sentOn: LocalDate, paymentDueOn: LocalDate) extends InvoiceEvent
![Page 38: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/38.jpg)
Exploring lightweight event sourcing
Domain Code
18
sealed trait InvoiceEventcase class InvoiceCreated() extends InvoiceEventcase class InvoiceRecipientChanged(recipient: String) extends InvoiceEventcase class InvoiceItemAdded(item: InvoiceItem, totalAmount: BigDecimal) extends InvoiceEventcase class InvoiceSent(sentOn: LocalDate, paymentDueOn: LocalDate) extends InvoiceEvent
sealed trait Invoice extends AggregateRoot { protected[this] type Event = InvoiceEvent}
![Page 39: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/39.jpg)
Exploring lightweight event sourcing
Domain Code
19
case class DraftInvoice( recipient: Option[String] = None, nextItemId: Int = 1, items: Map[Int, InvoiceItem] = Map.empty) extends Invoice {
def changeRecipient(recipient: String): Behavior[DraftInvoice] = ...
def addItem(description: String, amount: BigDecimal): Behavior[DraftInvoice] = ...
def send(sentOn: LocalDate): Behavior[Either[String, SentInvoice]] = ...
...
private def recipientChanged = when[InvoiceRecipientChanged] { event => copy(recipient = Some(event.recipient)) } private def itemAdded = when[InvoiceItemAdded] { event => copy(nextItemId = event.item.id + 1, items = items + (event.item.id -> event.item)) } private def sent = when[InvoiceSent] { event => SentInvoice(event.sentOn, event.paymentDueOn) }
}
![Page 40: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/40.jpg)
Exploring lightweight event sourcing
Domain Code
19
case class DraftInvoice( recipient: Option[String] = None, nextItemId: Int = 1, items: Map[Int, InvoiceItem] = Map.empty) extends Invoice {
def changeRecipient(recipient: String): Behavior[DraftInvoice] = ...
def addItem(description: String, amount: BigDecimal): Behavior[DraftInvoice] = ...
def send(sentOn: LocalDate): Behavior[Either[String, SentInvoice]] = ...
...
private def recipientChanged = when[InvoiceRecipientChanged] { event => copy(recipient = Some(event.recipient)) } private def itemAdded = when[InvoiceItemAdded] { event => copy(nextItemId = event.item.id + 1, items = items + (event.item.id -> event.item)) } private def sent = when[InvoiceSent] { event => SentInvoice(event.sentOn, event.paymentDueOn) }
}
The “Brains”
![Page 41: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/41.jpg)
Exploring lightweight event sourcing
Domain Code
19
case class DraftInvoice( recipient: Option[String] = None, nextItemId: Int = 1, items: Map[Int, InvoiceItem] = Map.empty) extends Invoice {
def changeRecipient(recipient: String): Behavior[DraftInvoice] = ...
def addItem(description: String, amount: BigDecimal): Behavior[DraftInvoice] = ...
def send(sentOn: LocalDate): Behavior[Either[String, SentInvoice]] = ...
...
private def recipientChanged = when[InvoiceRecipientChanged] { event => copy(recipient = Some(event.recipient)) } private def itemAdded = when[InvoiceItemAdded] { event => copy(nextItemId = event.item.id + 1, items = items + (event.item.id -> event.item)) } private def sent = when[InvoiceSent] { event => SentInvoice(event.sentOn, event.paymentDueOn) }
}
The “Brains”
The “Muscle”
![Page 42: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/42.jpg)
Exploring lightweight event sourcing
Domain Code
20
case class DraftInvoice( recipient: Option[String] = None, nextItemId: Int = 1, items: Map[Int, InvoiceItem] = Map.empty) extends Invoice {
def changeRecipient(recipient: String): Behavior[DraftInvoice] = recipientChanged(InvoiceRecipientChanged(recipient))
def addItem(description: String, amount: BigDecimal): Behavior[DraftInvoice] = itemAdded(InvoiceItemAdded(InvoiceItem(nextItemId, description, amount), totalAmount + amount))
def send(sentOn: LocalDate): Behavior[Either[String, SentInvoice]] = if (readyToSend_?) for (updated <- sent(InvoiceSent(sentOn, paymentDueOn = sentOn.plusDays(14)))) yield Right(updated) else pure(Left("invoice not ready to send"))
private def totalAmount = items.values.map(_.amount).sum
private def readyToSend_? = recipient.isDefined && items.nonEmpty
...}
![Page 43: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/43.jpg)
Exploring lightweight event sourcing
Domain Code
21
case class DraftInvoice( recipient: Option[String] = None, nextItemId: Int = 1, items: Map[Int, InvoiceItem] = Map.empty) extends Invoice {
...
protected[this] def applyEvent = recipientChanged orElse itemAdded orElse sent
...}
![Page 44: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/44.jpg)
Exploring lightweight event sourcing
Minimal Infrastructure
• Store only the domain events, replay these on application startup to reconstruct current state
• Keep the current state in-memory
• Use immutability data to reduce need for cloning or locking
22
![Page 45: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/45.jpg)
Exploring lightweight event sourcing
Simple functionality example
• “CRUD”: no domain logic, so no aggregate
• So we’ll persist events directly from the UI
• Useful to get started
• ... and even complex applications still contain simple functionality
23
![Page 46: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/46.jpg)
Exploring lightweight event sourcing
Aggregate Example
24
![Page 47: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/47.jpg)
Exploring lightweight event sourcing
Implementation Limitations
• Serializing (“big lock”) event store
• ~ 50 transactions per second
• Number of events to replay on startup
• ~ 30.000 JSON serialized events per second
• Total number of objects to store in main memory
• JVM can run with large heaps
25
![Page 48: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/48.jpg)
Exploring lightweight event sourcing
But ready to scale
• Advanced event store implementations support SQL, MongoDB, Amazon SimpleDB, etc.
• Use persisted view model for high volume objects (fixes startup time and memory usage)
• Easy partitioning of aggregates (consistency boundary with unique identifier)
• Load aggregates on-demand, use snapshotting
26
![Page 49: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/49.jpg)
Exploring lightweight event sourcing
Conclusion
• Event Sourcing captures full historical information
• Fully encapsulated domain code highly decoupled from persistence mechanism
• Simpler to implement and fully understand than traditional ORM based approach
• “Paradigm” shift towards Event-Driven
27
![Page 50: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/50.jpg)
Thanks!
![Page 51: Exloring Lightweight Event Sourcing - Scala Days 2011](https://reader033.fdocuments.us/reader033/viewer/2022042813/5472cd40b4af9fae0a8b50a6/html5/thumbnails/51.jpg)
Exploring lightweight event sourcing
References• Example code https://github.com/erikrozendaal/scala-event-sourcing-example
• CQRS http://cqrsinfo.com/
• Greg Young, “Unshackle Your Domain”http://www.infoq.com/presentations/greg-young-unshackle-qcon08
• Pat Helland, “Life Beyond Distributed Transactions: An Apostate's Opinion” http://www.ics.uci.edu/~cs223/papers/cidr07p15.pdf
• Erik Rozendaal, “Towards an immutable domain model” http://blog.zilverline.com/2011/02/10/towards-an-immutable-domain-model-monads-part-5/
• Frameworks: http://www.axonframework.org/ (Java) and http://ncqrs.org/ (.NET)
• Event store: https://github.com/joliver/EventStore (.NET) with over 20 supported data stores
29