diff --git a/akka-core/src/main/scala/stm/TransactionFactory.scala b/akka-core/src/main/scala/stm/TransactionFactory.scala index 7c6cfce536..26c255e6cf 100644 --- a/akka-core/src/main/scala/stm/TransactionFactory.scala +++ b/akka-core/src/main/scala/stm/TransactionFactory.scala @@ -4,6 +4,8 @@ package se.scalablesolutions.akka.stm +import java.lang.{Boolean => JBoolean} + import se.scalablesolutions.akka.config.Config._ import se.scalablesolutions.akka.util.Duration @@ -16,16 +18,17 @@ import org.multiverse.api.TraceLevel * For configuring multiverse transactions. See TransactionConfig class for options. */ object TransactionConfig { + // note: null values are so that we can default to Multiverse inference when not set val FAMILY_NAME = "DefaultTransaction" - val READONLY = false + val READONLY = null.asInstanceOf[JBoolean] val MAX_RETRIES = config.getInt("akka.stm.max-retries", 1000) val TIMEOUT = config.getLong("akka.stm.timeout", Long.MaxValue) val TIME_UNIT = config.getString("akka.stm.time-unit", "seconds") - val TRACK_READS = config.getBool("akka.stm.track-reads", false) + val TRACK_READS = null.asInstanceOf[JBoolean] val WRITE_SKEW = config.getBool("akka.stm.write-skew", true) val EXPLICIT_RETRIES = config.getBool("akka.stm.explicit-retries", false) val INTERRUPTIBLE = config.getBool("akka.stm.interruptible", false) - val SPECULATIVE = config.getBool("akka.stm.speculative", false) + val SPECULATIVE = config.getBool("akka.stm.speculative", true) val QUICK_RELEASE = config.getBool("akka.stm.quick-release", true) val TRACE_LEVEL = traceLevel(config.getString("akka.stm.trace-level", "none")) val HOOKS = config.getBool("akka.stm.hooks", true) @@ -39,10 +42,10 @@ object TransactionConfig { } def apply(familyName: String = FAMILY_NAME, - readonly: Boolean = READONLY, + readonly: JBoolean = READONLY, maxRetries: Int = MAX_RETRIES, timeout: Duration = DefaultTimeout, - trackReads: Boolean = TRACK_READS, + trackReads: JBoolean = TRACK_READS, writeSkew: Boolean = WRITE_SKEW, explicitRetries: Boolean = EXPLICIT_RETRIES, interruptible: Boolean = INTERRUPTIBLE, @@ -72,10 +75,10 @@ object TransactionConfig { * @param hooks Whether hooks for persistence modules and JTA should be added to the transaction. */ class TransactionConfig(val familyName: String = TransactionConfig.FAMILY_NAME, - val readonly: Boolean = TransactionConfig.READONLY, + val readonly: JBoolean = TransactionConfig.READONLY, val maxRetries: Int = TransactionConfig.MAX_RETRIES, val timeout: Duration = TransactionConfig.DefaultTimeout, - val trackReads: Boolean = TransactionConfig.TRACK_READS, + val trackReads: JBoolean = TransactionConfig.TRACK_READS, val writeSkew: Boolean = TransactionConfig.WRITE_SKEW, val explicitRetries: Boolean = TransactionConfig.EXPLICIT_RETRIES, val interruptible: Boolean = TransactionConfig.INTERRUPTIBLE, @@ -113,10 +116,10 @@ object TransactionFactory { def apply(config: TransactionConfig, defaultName: String) = new TransactionFactory(config, defaultName) def apply(familyName: String = TransactionConfig.FAMILY_NAME, - readonly: Boolean = TransactionConfig.READONLY, + readonly: JBoolean = TransactionConfig.READONLY, maxRetries: Int = TransactionConfig.MAX_RETRIES, timeout: Duration = TransactionConfig.DefaultTimeout, - trackReads: Boolean = TransactionConfig.TRACK_READS, + trackReads: JBoolean = TransactionConfig.TRACK_READS, writeSkew: Boolean = TransactionConfig.WRITE_SKEW, explicitRetries: Boolean = TransactionConfig.EXPLICIT_RETRIES, interruptible: Boolean = TransactionConfig.INTERRUPTIBLE, @@ -139,19 +142,28 @@ class TransactionFactory(val config: TransactionConfig = DefaultTransactionConfi // use the config family name if it's been set, otherwise defaultName - used by actors to set class name as default val familyName = if (config.familyName != TransactionConfig.FAMILY_NAME) config.familyName else defaultName - val factory = (getGlobalStmInstance().asInstanceOf[AlphaStm].getTransactionFactoryBuilder() - .setFamilyName(familyName) - .setReadonly(config.readonly) - .setMaxRetries(config.maxRetries) - .setTimeoutNs(config.timeout.toNanos) - .setReadTrackingEnabled(config.trackReads) - .setWriteSkewAllowed(config.writeSkew) - .setExplicitRetryAllowed(config.explicitRetries) - .setInterruptible(config.interruptible) - .setSpeculativeConfigurationEnabled(config.speculative) - .setQuickReleaseEnabled(config.quickRelease) - .setTraceLevel(config.traceLevel) - .build()) + val factory = { + var builder = (getGlobalStmInstance().asInstanceOf[AlphaStm].getTransactionFactoryBuilder() + .setFamilyName(familyName) + .setMaxRetries(config.maxRetries) + .setTimeoutNs(config.timeout.toNanos) + .setWriteSkewAllowed(config.writeSkew) + .setExplicitRetryAllowed(config.explicitRetries) + .setInterruptible(config.interruptible) + .setSpeculativeConfigurationEnabled(config.speculative) + .setQuickReleaseEnabled(config.quickRelease) + .setTraceLevel(config.traceLevel)) + + if (config.readonly ne null) { + builder = builder.setReadonly(config.readonly.booleanValue) + } // otherwise default to Multiverse inference + + if (config.trackReads ne null) { + builder = builder.setReadTrackingEnabled(config.trackReads.booleanValue) + } // otherwise default to Multiverse inference + + builder.build() + } val boilerplate = new TransactionBoilerplate(factory)