Protected
Protected

Transactors


Actors are excellent for solving problems where you have many independent processes that can work in isolation and only interact with other Actors through message passing. This model fits many problems. But the actor model is unfortunately a terrible model for implementing truly shared state. E.g. when you need to have consensus and a stable view of state across many components. The classic example is the bank account where clients can deposit and withdraw, in which each operation needs to be atomic. For detailed discussion on the topic see this JavaOne presentation.

STM
on the other hand is excellent for problems where you need consensus and a stable view of the state by providing compositional transactional shared state. Some of the really nice traits of STM are that transactions compose, and it raises the abstraction level from lock-based concurrency.

Akka's Transactors, e.g. being able to optionally combine Actors and STM provides IMHO the best of the Actor model (concurrency and asynchronous event-based programming) and STM (compositional transactional shared state) by providing transactional, compositional, asynchronous, event-based message flows.

If you need Durability then you should not use one of the in-memory data structures but one of the persistent ones.

You can define an Active Object and Actor to have transaction required semantics. This means that if it is invoked outside the scope of a transaction then a new transaction will always be started, but if it already is in a transaction then that transaction will be joined.

You can configure an Actor or Active Object to be transactional either declaratively or programatically.

Declarative configuration


You can configure an Actor or Active Object to be fully transactional, e.g. every message it receives will be received within a transaction. In Actors it's done with traits and in Active Objects with annotations.

Transactional Actors


Transaction required semantics for an Actor is defined by mixing in the 'Transactor' trait instead of the 'Actor' trait:

import se.scalablesolutions.akka.actor.Transactor
 
class MyActor extends Transactor {
  ...
}

You can also enable transaction required semantics for an Actor by invoking the ‘makeTransactionRequired’ method:

class MyActor extends Actor {
  makeTransactionRequired
  ...
}

Finally you can also enable transaction required semantics for an Actor by invoking mixing in the 'TransactionRequired’ trait:

class MyActor extends Actor with TransactionRequired {
  ...
}

Creating transactional datastructures within an Actor


If you create a transactional Ref, Vector or Map in the constructor of the Transactor then you have to declare it a 'lazy' to ensure that it is created within the scope of a transaction. Another way would be to create the datastructure inside an 'atomic { ... }' block.

Transactional Active Objects


Transaction required semantics for an Active Object is defined by adding the ‘se.scalablesolutions.akka.annotation.transactionrequired’ annotation to the class:

@transactionrequired
class POJO {
...
}

Programmatic configuration


You can configure an Actor or Active Object to be transactional only for the messages you want using the programmatic Transaction API. This also gives you more flexibility in how you define the transaction semantics with the cost of more code.

See the STM section for details.
Home
close
Loading...
Home Turn Off "Getting Started"
close
Loading...