Concurrency and Transactions
Concurrency
  - When multiple threads access the same resources, care must be taken to
    ensure that data is accessed in a consistent manner. 
    
      - Example: Bank account transfer, academic record
 
- Atomic operations execute without interference from other operations. 
    
      - Is a += 1an atomic operation?
- See java.util.concurrent.atomic package.
- Should a transfer or a GPA update be atomic?
 
- The Java keyword synchronized ensures that only 1 thread may
    access an object at any time. 
    
      - Bank account: getBalance, setBalance, deposit, withdraw
- Is this too restrictive?
 
Conflicts
  - Operations are read or write.
- Conflicts occur if the order in which operations are executed impacts
    the result.
- Write/write and read/write are conflicting operations.
- Read/read is OK.
Locking
  - Retrieve a lock on a resource before accessing it.
- Rules: 
    
      - if requested lock is read and (no lock held or read lock held):
        grant read lock
- if requested lock is read and write lock held: wait
- if requested lock is write and no lock held: grant write lock
- if requested lock is write and (read lock held or write lock held):
        wait
 
- Java's wait/notify enable threads to communicate. wait blocks
    waiting for a lock. notify releases a lock and notifies all those waiting
    for the lock.
Models for XML DB Thread Safety
  - Synchronize all - the most restrictive model that does not allow
    concurrent reads.
- Copy update - make changes to a copy of the DB and replace old with an
    (atomic) assignment. Keeps two copies of DB in memory during update.
- Locking - no one attempted.
Transactions
  - A transaction is a series of operations between a client and
  server.
- Goals: 
    
      - Objects remain in consistent state
- System is tolerant to crash failures
- Transactions are independent
- Transactions are completed or not started
 
- Example: bank account transfer
Commit/Abort
  - A transaction is committed or aborted.
- Commit - all operations completed, results are written to permanent
    storage, operation cannot be undone.
- Abort - transaction cannot be completed, all operations are undone.
ACID
  - Acronym used to refer to the properties of transactions.
- Atomicity, Consistency, Isolation, Durability
Atomicity
  - "all-or-nothing"
- Either a transaction completes successfully, and all effects are
    applied to all objects, or it has no effect all all.
Consistency
  - A transaction must move the system from one consistent state to another
    consistent state.
- Example: sum of all account balances equal to branch's total
  accounts
Isolation
  - The intermediate effects of a transaction must not be visible to other
    transactions.
- Example: for an account transfer, cannot see accounts after withdrawal
    but before deposit
Durability
  - After a transaction has been processed, its effects are saved to
    permanent storage.
Problems in Transaction Processing: Lost Updates
  - One transaction may overwrite the result of another.
- Example: Transaction T wants to increase b's balance by 10%,
    transferring from a. 
    
      - bal = b.getBalance()
- b.setBalance(bal*1.1)
- a.withdraw(bal/10)
 
- Transaction U wants to increase b's balance by 10%, transferring from
    c. 
    
      - bal = b.getBalance()
- b.setBalance(bal*1.1)
- c.withdraw(bal/10)
 
- Problem: suppose order is T1, U1, U2, T2, T3, U3. Balance of b is $220
    (not $242 as it should be).
Problems in Transaction Processing: Inconsistent Retrievals
  - An inconsistent value may be reported if a transaction is in
  progress.
- Example: Transaction V transfers $100 from a to b. 
    
      - a.withdraw(100)
- b.deposit(100)
 
- Transaction W gets the total of all accounts at the bank branch. 
    
      - getBranchTotal()
 
- If W executes between V1 and V2, the total will be short $100.
Serial Equivalence
  - Interleaving of operations should produce the same effect as a
    non-interleaved execution. 
- From lost update example: T1, T2, U1, U2, T3, U3 is OK.
- Recall, write/write and read/write are conflicting. Read/read
    operations are not conflicting.
- For two transactions to be serially equivalent, all pairs of
    conflicting operations must execute in the same order on all objects they
    both access.
- Example: T: x=read(i); write(i, 10); write(j, 20) U: read(j); write(j,
    30); z=read(i)
- write(i, 10) and read(i) conflict -- write(j, 20) and read(j)
  conflict
- To be serially equivalent, (T must access i before U does AND T must
    access j before U does) OR (U must access i before T does and U must
    access j before T does).
Locking
  - The most common way to achieve serial equivalence is through the use of
    locks.
- Before a client accesses an object, it must acquire a lock on that
    object.
- A process may not acquire new locks within a transaction once a lock
    has been released. 
    
      - This is two-phase locking. There is a lock-growing phase
        and a lock-shrinking phase.
 
Locking Example
  - T1 - bal = b.getBalance() - Transaction T locks b
- T2 - b.setBalance(bal*1.1)
- U begins
- T3 - a.withdraw(bal/10) - Transaction T locks a
- U1 - bal = b.getBalance() - b locked, U must wait
- T completes - a and b unlocked
- U locks b - gets balance
- U2 - b.setBalance(bal*1.1)
- U3 - c.withdraw(bal/10) - Transaction U locks c
- U completes - b and c unlocked
Strict Two-Phase Locking
  - All locks are held until transaction is committed.
- Prevents dirty reads and premature writes.
- Dirty read - a transaction sees a value that is part of another
    transaction that is later aborted 
    
      - T1: bal1 = a.getBalance() ($100)
- T2: a.setBalance(bal1+10) ($110)
- U1: bal2 = a.getBalance() ($110)
- U2: a..setBalance(bal2+20) ($130)
- U commits
- T aborts
- U cannot be undone
 
- Premature write - an aborted operation is reset to the wrong value 
    
      - Some systems store the before image with a write and roll back to
        that value in the event of an abort. This is a problem if another
        process overwrites the value before the abort.
- a - balance is $100
- T: a.setBalance($105) - (before image: 100)
- U: a.setBalance($110) - (before image: 105)
- U commits, T aborts and resets to 100 -- should be 110
- If T aborts then U aborts, result will be 105, but should be
      100.
 
Deadlocks
  - Two or more processes wait for lock held by other processes.
- Neither can proceed until it gives up the lock, and neither can give up
    the lock until it proceeds.
- Example: 
    
      - T: a.deposit(100); b.withdraw(100)
- U: b.deposit(50); a.withdraw(50)
- T1: a.deposit(100) - locks a
- U1: b.deposit(50) - locks b
- T2: b.withdraw(100) - wait for lock on b
- U2: a.withdraw(50) - wait for lock on a
 
Preventing Deadlock
  - Atomically acquire all locks at beginning of transaction - very
    restrictive
- Specify order in which locks must be acquired - also restrictive
Detecting Deadlock
  - Have the process that grants locks force transactions to abort.
- Use a wait-for-graph where vertices are processes and edges
    are lock dependencies
- When a lock is requested an edge is added; when a lock is freed and
    edge is removed.
- If the graph has a cycle, there is a deadlock.
- The transaction of one of the processes must be aborted.
Distributed Transactions
  - A transaction that accesses objects at multiple servers. 
- If a transaction commits at one server, it must commit at all
  servers.
- If a transaction aborts at one server, it must abort at all
  servers.
- A coordinator process manages the transaction. The coordinator is a
    process on one of the servers.
- Each server that manages an object used in the transaction is a
    participant. 
- When a participant joins, it informs the coordinator.

Two-phase Commit
  - The coordinator uses two-phase commit to ensure that all participants
    either commit or abort.
- Phase 1: The coordinator asks each participant whether it can commit. A
    participant may not change its vote to abort once it has voted to
  commit.
- Phase 2: Once all participants have voted, if any participant voted to
    abort then an abort is sent to all participants. If all participants
    voted to commit then a commit is sent to all participants. 
- The participants inform the coordinator that they have committed.
Failure in Two-phase Commit
  - Server crash: To address the failure of a participant server, servers
    store the state of the transaction to permanent storage so that the
    process may be restarted and recover.
- Communication failure: To address communication failure, timeouts are
    used. If the coordinator times out waiting for participants to vote, it
    will eventually decide to abort. If a participant times out waiting for
    the final vote from the coordinator, it will ping the coordinator. if the
    coordinator has failed, the participant will wait for it to be restarted.
  
Distributed Deadlock
  - Deadlock can occur in distributed transactions. 
- Example: T locks object X on server A; U locks object Y on server B; T
    blocks waiting to lock object Y on server B; U blocks waiting to lock
    object X on server A.
- A simple approach to deadlock detection: all lock managers send
    information to a central authority. This approach comes with all of the
    usual problems of a centralized solution.
Edge Chasing
  - Edge chasing is a distributed approach to detecting
  deadlock.
- Each lock manager keeps a graph of the edges it knows about and sends
    probes that follow the edges and attempt to detect cycles.
- When a transaction begins waiting for a lock, the coordinator is
    informed.
- When a process receives a request for a lock, and another transaction
    is holding that lock, it checks with the coordinator to see if the other
    process is waiting.
- If it is, it sends a probe to the server administering that lock, which
    includes the wait-for-graph.
- As probes are forwarded, edges are added and cycles are detected.

Breaking Deadlock
  - To break deadlock, transactions are aborted.
- Transactions are given globally unique priority IDs and the lowest
    priority is aborted.
  Sami Rollins 
Date: 2008-03-27