# Software Transaction memory

## What is that about

### OndŘej Chaloupka

``int x = 0, y = 0, z = 0;``
``````void first {
x = x + 1;
}``````
``````void second {
y = y + 1;
x = x + 1;
}``````
``````void third {
z = z + 1;
y = y + 1;
x = x + 1;
}``````

## Running in pararell

``int x = 0, y = 0, z = 0;``
``````void first {
x = x + 1;
}``````
``````void second {
y = y + 1;
x = x + 1;
}``````
``````void third {
z = z + 1;
y = y + 1;
x = x + 1;
}``````

## Running in pararell

``x == 3, y == 2, z == 1 ???``
``int x = 0, y = 0, z = 0;``
``````void first {
synchronized(this) {
x = x + 1;
}
}``````
``````void second {
synchronized(this) {
y = y + 1;
x = x + 1;
}
}``````
``````void third {
synchronized(this) {
z = z + 1;
y = y + 1;
x = x + 1;
}
}``````
``x == 3, y == 2, z == 1 !``
``txn_int x = 0, y = 0, z = 0;``
``````void first {
atomic {
x = x + 1;
}
}``````
``````void second {
atomic {
y = y + 1;
x = x + 1;
}
}``````
``````void third {
atomic {
z = z + 1;
y = y + 1;
x = x + 1;
}
}``````
``x == 3, y == 2, z == 1 !!!``
``````class Account {
int balance;
synchronized void withdraw(int n) {
balance = balance - n;
}

void deposit(int n) {
withdraw(-n);
}
}

class Transfer  {
void transfer(Account from, Account to, int amount) {
from.withdraw(amount);
to.deposit(amount);
}
}``````

## Locks are not composable

``````class Account {
int balance;
synchronized void withdraw(int n) {
balance = balance - n;
}

void deposit(int n) {
withdraw(-n);
}
}

class Transfer  {
void transfer(Account from, Account to, int amount) {
synchronized(from) {
synchronized(to) {
from.withdraw(amount);
to.deposit(amount);
}
}
}
}``````
``````class Account {
txn_int balance;
void withdraw(int n) {
atomic {
balance = balance - n;
}
}

void deposit(int n) {
withdraw(-n);
}
}

class Transfer  {
void transfer(Account from, Account to, int amount) {
atomic {
from.withdraw(amount);
to.deposit(amount);
}
}
}``````

## Software transaction memory

• A concurrency models which uses shared memory
• An alternative to the lock-based synchronization approach
• Grouping memory operations for them running atomically
• Simple interface for developers
• Can be implemented in various but not easy ways

## Why "transactional" (STM)

• ACI(D) properties for the program
• Atomically - either all operations are done or non of them
• Consistency
• Isolation - no influencing each other
• serializable - operations appears like processing one after another
(even system hardly thrive to process in parallel)
• D - not usual, Narayana uses transaction log store to provide  it

## HOW IT WORKS

``````void second {
atomic {
y = y + 1;
x = x + 1;
}
}``````

Handle/Proxy

Memory

``````void third {
atomic {
z = z + 1;
y = y + 1;
x = x + 1;
}
}``````

## HOW IT WORKS

``````void second {
atomic {
y = y + 1;
x = x + 1;
}
}``````

x =0

y =0

y =1

x =1

Memory

Write-set

# Narayana STM

``````public class Container<T> {
public enum TYPE { RECOVERABLE, PERSISTENT };
public enum MODEL { SHARED, EXCLUSIVE };
public Container ();
public synchronized T create (T member);
public static final Container<?>
getContainer (Object proxy);
}
``````

# Narayana STM

``````@Transactional
public interface StockLevel {
int get () throws Exception;
void set (int value) throws Exception;
void decr (int value) throws Exception;
}
``````

# Narayana STM

``````Container<StockLevel> container = new Container<>();
StockLevelImpl stock = new StockLevelImpl();

StockLevel stockWrapped = container.create(stock);

// update the STM object inside a transaction
// or use annotations to define transaction boundaries
AtomicAction a = new AtomicAction();

a.begin();
stockWrapped.set(1234);
a.commit();
``````

# Narayana STM

``````// Implementations of interface
// are container managed
@Transactional

// Container will create
// a new transaction for each method
@Nested & @NestedTopLevel

@Optimistic & @Pessimistic