diff --git a/akka-stm/src/main/scala/actor/Transactor.scala b/akka-stm/src/main/scala/actor/Transactor.scala index 3baf4d81c0..a23db1de7a 100644 --- a/akka-stm/src/main/scala/actor/Transactor.scala +++ b/akka-stm/src/main/scala/actor/Transactor.scala @@ -14,18 +14,20 @@ object Transactor { } /** - * Transactor - an actor with built-in support for coordinated transactions. - *
- * Transactors implement the general pattern for using Coordinated where first - * any coordination messages are sent to other transactors, then the coordinated + * An actor with built-in support for coordinated transactions. + * + * Transactors implement the general pattern for using [[akka.stm.Coordinated]] where + * first any coordination messages are sent to other transactors, then the coordinated * transaction is entered. - * - * Simple transactors will just implement the 'atomically' method, similar to - * the actor 'receive' method, but which runs within a coordinated transaction. - * + * Transactors can also accept explicitly sent `Coordinated` messages. + *
+ *
+ * {{{
* class Counter extends Transactor {
* val count = Ref(0)
*
@@ -33,18 +35,19 @@ object Transactor {
* case Increment => count alter (_ + 1)
* }
* }
- *
- *
- * To coordinate with other transactors override the 'coordinate' method.
- * The 'coordinate' method matches messages to a set of 'SendTo' objects,
- * a pair of ActorRef and Message. You can use the 'include' and 'sendTo' methods
- * to easily coordinate with other transactors. The 'include' method will send
- * on the same message that was received to other transactors. The 'sendTo' method
- * allows you to specify both the actor to send to, and message to send.
- *
- * Example of using coordinate:
- *
- * + * }}} + *- * - * Using 'include' to include more than one transactor: - * - *
+ * + * To coordinate with other transactors override the `coordinate` method. + * The `coordinate` method maps a message to a set + * of [[akka.actor.Transactor.SendTo]] objects, pairs of `ActorRef` and a message. + * You can use the `include` and `sendTo` methods to easily coordinate with other transactors. + * The `include` method will send on the same message that was received to other transactors. + * The `sendTo` method allows you to specify both the actor to send to, and message to send. + * + * Example of using coordinating an increment: + * + * {{{ * class FriendlyCounter(friend: ActorRef) extends Transactor { * val count = Ref(0) * @@ -56,37 +59,40 @@ object Transactor { * case Increment => count alter (_ + 1) * } * } - *
+ * }}} + *- * - * Using 'sendTo' to coordinate transactions but send on a different message + * }}} + *
+ * + * Using `include` to include more than one transactor: + * + * {{{ * override def coordinate = { * case Message => include(actor1, actor2, actor3) * } - *
+ *
+ * {{{
* override def coordinate = {
* case Message => sendTo(someActor -> SomeOtherMessage)
* case SomeMessage => sendTo(actor1 -> Message1, actor2 -> Message2)
* }
- *
- *
+ * }}}
+ *
+ *
+ * Example usage ''(Java)''
+ *
+ * {{{
* import akka.stm.*;
*
* final Ref ref = new Ref(0);
@@ -31,7 +31,7 @@ package akka.stm
* return ref.get();
* }
* }.execute();
- *
+ * }}}
*/
abstract class Atomic[T](factory: TransactionFactory) {
def this() = this(DefaultTransactionFactory)
diff --git a/akka-stm/src/main/scala/stm/Coordinated.scala b/akka-stm/src/main/scala/stm/Coordinated.scala
index f025be3053..a722dc3636 100644
--- a/akka-stm/src/main/scala/stm/Coordinated.scala
+++ b/akka-stm/src/main/scala/stm/Coordinated.scala
@@ -21,52 +21,62 @@ object Coordinated {
}
/**
- * Coordinated transactions across actors.
- *
- * Coordinated is a wrapper for any message that adds a CountDownCommitBarrier to
- * coordinate transactions across actors or threads. To start a new coordinated transaction
- * that you will also participate in, use:
- *
- * + * `Coordinated` is a message wrapper that adds a `CountDownCommitBarrier` for explicitly + * coordinating transactions across actors or threads. + * + * Creating a `Coordinated` will create a count down barrier with initially one member. + * For each member in the coordination set a transaction is expected to be created using + * the coordinated atomic method. The number of included parties must match the number of + * transactions, otherwise a successful transaction cannot be coordinated. + *- * - * Creating a Coordinated object will create a count down barrier with one member. For each - * member in the coordination set a coordinated transaction is expected to be created. - * - * To start a coordinated transaction in another actor that you won't participate in yourself - * can send the Coordinated message directly and the recipient is the first member of the - * coordinating actors: - * - *
+ * + * To start a new coordinated transaction set that you will also participate in just create + * a `Coordinated` object: + * + * {{{ * val coordinated = Coordinated() - *
+ * }}} + *- * - * To receive a coordinated message in an actor: - * - *
+ * + * To start a coordinated transaction that you won't participate in yourself you can create a + * `Coordinated` object with a message and send it directly to an actor. The recipient of the message + * will be the first member of the coordination set: + * + * {{{ * actor ! Coordinated(Message) - *
+ * }}} + *- * + * }}} + *
+ * + * To receive a coordinated message in an actor simply match it in a case statement: + * + * {{{ * def receive = { * case coordinated @ Coordinated(Message) => ... * } - *
+ * involved by one and create a new `Coordinated` object to be sent.
+ *
+ * {{{
* actor ! coordinated(Message)
- *
- *
- * To enter a coordinated transaction use the atomic method of the Coordinated object:
- *
- * + * }}} + *- * + * }}} + * + * The coordinated transaction will wait for the other transactions before committing. + * If any of the coordinated transactions fail then they all fail. + * + * @see [[akka.actor.Transactor]] for an actor that implements coordinated transactions */ class Coordinated(val message: Any, barrier: CountDownCommitBarrier) { def apply(msg: Any) = { diff --git a/akka-stm/src/main/scala/stm/Ref.scala b/akka-stm/src/main/scala/stm/Ref.scala index 1bb8779b1b..3c5237388a 100644 --- a/akka-stm/src/main/scala/stm/Ref.scala +++ b/akka-stm/src/main/scala/stm/Ref.scala @@ -28,12 +28,12 @@ object Ref { * To ensure safety the value stored in a Ref should be immutable (they can also * contain refs themselves). The value referenced by a Ref can only be accessed * or swapped within a transaction. If a transaction is not available, the call will - * be executed in its own transaction (equivalent to using the Ref.atomic* methods). + * be executed in its own transaction. + *
+ * + * To enter the coordinated transaction use the atomic method of the coordinated object: + * + * {{{ * coordinated atomic { - * // Do something in transaction that will wait for the other transactions before committing. - * // If any of the coordinated transactions fail then they all fail. + * // do something in transaction ... * } - *
+ * Creating a Ref ''(Scala)''
+ *
+ * {{{
* import akka.stm._
*
* // giving an initial value
@@ -41,12 +41,12 @@ object Ref {
*
* // specifying a type but no initial value
* val ref = Ref[Int]
- *
+ * }}}
+ *
+ * Creating a Ref ''(Java)''
+ *
+ * {{{
* import akka.stm.*;
*
* // giving an initial value
@@ -54,7 +54,7 @@ object Ref {
*
* // specifying a type but no initial value
* final Ref ref = new Ref();
- *
+ * }}}
*/
class Ref[T](initialValue: T) extends BasicRef[T](initialValue) with Transactional {
self =>
diff --git a/akka-stm/src/main/scala/stm/Stm.scala b/akka-stm/src/main/scala/stm/Stm.scala
index f9bf1cec6a..44f639ae22 100644
--- a/akka-stm/src/main/scala/stm/Stm.scala
+++ b/akka-stm/src/main/scala/stm/Stm.scala
@@ -9,21 +9,26 @@ import org.multiverse.api.{Transaction => MultiverseTransaction}
import org.multiverse.templates.{TransactionalCallable, OrElseTemplate}
/**
- * Stm trait that defines the atomic block for local transactions.
- *
- * If you need to coordinate transactions across actors @see Coordinated.
- *
- * Example of atomic transaction management using the atomic block (in Scala).
- *
- *
- * import akka.stm._
+ * Defines the atomic block for local transactions. Automatically imported with:
*
+ * {{{
+ * import akka.stm._
+ * }}}
+ *
+ *
+ * If you need to coordinate transactions across actors see [[akka.stm.Coordinated]].
+ *
+ *
+ * Example of using the atomic block ''(Scala)''
+ *
+ * {{{
* atomic {
* // do something within a transaction
* }
- *
- *
- * @see Atomic for creating atomic blocks in Java.
+ * }}}
+ *
+ * @see [[akka.stm.Atomic]] for creating atomic blocks in Java.
+ * @see [[akka.stm.StmUtil]] for useful methods to combine with `atomic`
*/
trait Stm {
val DefaultTransactionFactory = TransactionFactory(DefaultTransactionConfig, "DefaultTransaction")
@@ -42,7 +47,61 @@ trait Stm {
}
/**
- * Stm utils for scheduling transaction lifecycle tasks and for blocking transactions.
+ * Stm utility methods for scheduling transaction lifecycle tasks and for blocking transactions.
+ * Automatically imported with:
+ *
+ * {{{
+ * import akka.stm._
+ * }}}
+ *
- * either {
- * ...
- * } orElse {
- * ...
- * }
- *
*/
def either[T](firstBody: => T) = new {
def orElse(secondBody: => T) = new OrElseTemplate[T] {
diff --git a/akka-stm/src/main/scala/stm/Transaction.scala b/akka-stm/src/main/scala/stm/Transaction.scala
index 1509bd29d8..0fa38a0ff9 100644
--- a/akka-stm/src/main/scala/stm/Transaction.scala
+++ b/akka-stm/src/main/scala/stm/Transaction.scala
@@ -202,7 +202,7 @@ trait Abortable {
}
/**
- * For reflective access to the JTA module.
+ * Used internally for reflective access to the JTA module.
* Allows JTA integration to work when akka-jta.jar is on the classpath.
*/
object ReflectiveJtaModule {
diff --git a/akka-stm/src/main/scala/stm/TransactionFactory.scala b/akka-stm/src/main/scala/stm/TransactionFactory.scala
index d348aee8a5..a6c847002b 100644
--- a/akka-stm/src/main/scala/stm/TransactionFactory.scala
+++ b/akka-stm/src/main/scala/stm/TransactionFactory.scala
@@ -149,23 +149,23 @@ object TransactionFactory {
/**
* Wrapper for transaction config, factory, and boilerplate. Used by atomic.
* Can be passed to atomic implicitly or explicitly.
- *
- *
+ *
+ * {{{
* implicit val txFactory = TransactionFactory(readonly = true)
* ...
* atomic {
* // do something within a readonly transaction
* }
- *
- *
+ * }}}
+ *
* Can be created at different levels as needed. For example: as an implicit object
* used throughout a package, as a static implicit val within a singleton object and
* imported where needed, or as an implicit val within each instance of a class.
- *
+ *
* If no explicit transaction factory is passed to atomic and there is no implicit
* transaction factory in scope, then a default transaction factory is used.
*
- * @see TransactionConfig for configuration options.
+ * @see [[akka.stm.TransactionConfig]] for configuration options.
*/
class TransactionFactory(
val config: TransactionConfig = DefaultTransactionConfig,