2009-06-29 15:01:20 +02:00
|
|
|
/**
|
2009-12-27 16:01:53 +01:00
|
|
|
* Copyright (C) 2009-2010 Scalable Solutions AB <http://scalablesolutions.se>
|
2009-06-29 15:01:20 +02:00
|
|
|
*/
|
|
|
|
|
|
2009-09-02 09:10:21 +02:00
|
|
|
package se.scalablesolutions.akka.stm
|
2009-06-29 15:01:20 +02:00
|
|
|
|
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean
|
|
|
|
|
|
2009-10-06 00:07:27 +02:00
|
|
|
import se.scalablesolutions.akka.util.Logging
|
|
|
|
|
|
2009-11-25 20:37:00 +01:00
|
|
|
import org.multiverse.api.ThreadLocalTransaction._
|
2010-02-23 19:49:01 +01:00
|
|
|
import org.multiverse.commitbarriers.CountDownCommitBarrier
|
2009-08-15 22:44:29 +02:00
|
|
|
|
2009-10-17 00:37:56 +02:00
|
|
|
class StmException(msg: String) extends RuntimeException(msg)
|
2009-06-29 15:01:20 +02:00
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
class TransactionAwareWrapperException(val cause: Throwable, val tx: Option[Transaction]) extends RuntimeException(cause) {
|
|
|
|
|
override def toString = "TransactionAwareWrapperException[" + cause + ", " + tx + "]"
|
2009-06-29 15:01:20 +02:00
|
|
|
}
|
|
|
|
|
|
2009-10-17 00:37:56 +02:00
|
|
|
object TransactionManagement extends TransactionManagement {
|
2009-10-06 00:07:27 +02:00
|
|
|
import se.scalablesolutions.akka.Config._
|
2009-11-30 10:11:52 +01:00
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
val TRANSACTION_ENABLED = new AtomicBoolean(config.getBool("akka.stm.service", false))
|
|
|
|
|
val FAIR_TRANSACTIONS = config.getBool("akka.stm.fair", true)
|
|
|
|
|
val INTERRUPTIBLE = config.getBool("akka.stm.interruptible", true)
|
|
|
|
|
val MAX_NR_OF_RETRIES = config.getInt("akka.stm.max-nr-of-retries", 1000)
|
|
|
|
|
val TRANSACTION_TIMEOUT = config.getInt("akka.stm.timeout", 10000)
|
|
|
|
|
val SMART_TX_LENGTH_SELECTOR = config.getBool("akka.stm.smart-tx-length-selector", true)
|
2009-07-04 12:06:07 +02:00
|
|
|
def isTransactionalityEnabled = TRANSACTION_ENABLED.get
|
2010-02-23 19:49:01 +01:00
|
|
|
|
2009-07-04 12:06:07 +02:00
|
|
|
def disableTransactions = TRANSACTION_ENABLED.set(false)
|
2009-06-29 15:01:20 +02:00
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] val transactionSet = new ThreadLocal[Option[CountDownCommitBarrier]]() {
|
|
|
|
|
override protected def initialValue: Option[CountDownCommitBarrier] = None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private[akka] val transaction = new ThreadLocal[Option[Transaction]]() {
|
2009-07-01 15:29:06 +02:00
|
|
|
override protected def initialValue: Option[Transaction] = None
|
2009-06-29 15:01:20 +02:00
|
|
|
}
|
2010-02-23 19:49:01 +01:00
|
|
|
|
|
|
|
|
private[akka] def getTransactionSet: CountDownCommitBarrier = {
|
|
|
|
|
val option = transactionSet.get
|
|
|
|
|
if ((option eq null) || option.isEmpty) throw new IllegalStateException("No TransactionSet in scope")
|
|
|
|
|
option.get
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private[akka] def getTransaction: Transaction = {
|
|
|
|
|
val option = transaction.get
|
|
|
|
|
if ((option eq null) || option.isEmpty) throw new IllegalStateException("No Transaction in scope")
|
|
|
|
|
option.get
|
|
|
|
|
}
|
2009-06-29 15:01:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait TransactionManagement extends Logging {
|
|
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] def createNewTransactionSet: CountDownCommitBarrier = {
|
|
|
|
|
val txSet = new CountDownCommitBarrier(1, TransactionManagement.FAIR_TRANSACTIONS)
|
|
|
|
|
TransactionManagement.transactionSet.set(Some(txSet))
|
|
|
|
|
txSet
|
2009-10-08 19:01:04 +02:00
|
|
|
}
|
|
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] def setTransactionSet(txSet: Option[CountDownCommitBarrier]) =
|
|
|
|
|
if (txSet.isDefined) TransactionManagement.transactionSet.set(txSet)
|
|
|
|
|
|
|
|
|
|
private[akka] def setTransaction(tx: Option[Transaction]) =
|
|
|
|
|
if (tx.isDefined) TransactionManagement.transaction.set(tx)
|
|
|
|
|
|
|
|
|
|
private[akka] def clearTransactionSet = TransactionManagement.transactionSet.set(None)
|
|
|
|
|
|
2009-10-17 00:37:56 +02:00
|
|
|
private[akka] def clearTransaction = {
|
2010-02-23 19:49:01 +01:00
|
|
|
TransactionManagement.transaction.set(None)
|
2009-10-08 19:01:04 +02:00
|
|
|
setThreadLocalTransaction(null)
|
2009-07-04 12:06:07 +02:00
|
|
|
}
|
|
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] def getTransactionSetInScope = TransactionManagement.getTransactionSet
|
2009-06-29 15:01:20 +02:00
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] def getTransactionInScope = TransactionManagement.getTransaction
|
2010-02-22 13:22:10 +01:00
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] def isTransactionSetInScope = {
|
|
|
|
|
val option = TransactionManagement.transactionSet.get
|
|
|
|
|
(option ne null) && option.isDefined
|
|
|
|
|
}
|
2009-06-29 15:01:20 +02:00
|
|
|
|
2010-02-23 19:49:01 +01:00
|
|
|
private[akka] def isTransactionInScope = {
|
|
|
|
|
val option = TransactionManagement.transaction.get
|
|
|
|
|
(option ne null) && option.isDefined
|
|
|
|
|
}
|
|
|
|
|
}
|