Skip to content

Instantly share code, notes, and snippets.

@vastdevblog
Created March 16, 2012 22:05
Show Gist options
  • Save vastdevblog/2053120 to your computer and use it in GitHub Desktop.
Save vastdevblog/2053120 to your computer and use it in GitHub Desktop.
Scala trait to add transactional support to a class.
package com.vast.example
import org.springframework.transaction.{TransactionStatus, PlatformTransactionManager}
import org.springframework.transaction.annotation.{Isolation, Propagation}
import org.springframework.transaction.support.{TransactionTemplate, DefaultTransactionDefinition, TransactionCallback}
/**
* Add a method to execute a block of code in a transaction. Typical use
*
* {{{
* class MyClass(val manager: PlatformTransactionManager)
* extends SomeClass with TransactionSupport {
*
* def someMethod() {
* inTransaction() {
* // Code that runs in a read only transaction
* }
* }
*
* def someOtherMethod() {
* inTransaction(readOnly = false) {
* // Code that runs in a read/write transaction
* }
* }
* }
* }}}
*
* where having SomeClass is optional, you can directly extend TransactionSupport
* if you want
*/
trait TransactionSupport {
/**
* Use def and not val to specify the transaction manager. It can be overridden
* with a val though.
* See http://stackoverflow.com/questions/7846119/is-there-something-wrong-with-an-abstract-value-used-in-trait-in-scala
*/
def manager: PlatformTransactionManager
/**
* Method to execute a block of code in a transaction.
*
* @param readOnly Defaults to false, set to true to get a read only transaction.
* @param propagation Type of transaction propagation, defaults to REQUIRED.
* @param isolation Isolation level, defaults to DEFAULT.
* @param value Call by name value.
* @tparam T Type of returned value.
* @return The result of evaluating value in the context of a transaction.
*/
def inTransaction[T](readOnly: Boolean = false,
propagation: Propagation = Propagation.REQUIRED,
isolation: Isolation = Isolation.DEFAULT)(value: => T): T = {
val transactionDef = new DefaultTransactionDefinition(propagation.value());
transactionDef.setIsolationLevel(isolation.value());
transactionDef.setReadOnly(readOnly);
new TransactionTemplate(manager, transactionDef).execute(new TransactionCallback[T] {
def doInTransaction(status: TransactionStatus) = value
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment