views:

51

answers:

1

Hello!

I've a question regarding distributed transactions. Let's assume I have 3 transaction programs:

Transaction A

  1. begin
  2. a=read(A)
  3. b=read(B)
  4. c=a+b
  5. write(C,c)
  6. commit

Transaction B

  1. begin
  2. a=read(A)
  3. a=a+1
  4. write(A,a)
  5. commit

Transaction C

  1. begin
  2. c=read(C)
  3. c=c*2
  4. write(A,c)
  5. commit

So there are 5 pairs of critical operations: C2-A5, A2-B4, B4-C4, B2-C4, A2-C4.

I should ensure integrity and confidentiality, do you have any idea of how to achieve it?

Thank you in advance!

A: 

What you have described in your post is a common situation in multi-user systems. Different sessions simultaneously start transactions using the same tables and indeed the same rows. There are two issues here:

  1. What happens if Session C reads a record after Session A has updated it but before Session A has committed its trandsaction?
  2. What happens if Session C updates the same record which Session A has updated but not committed?

(Your scenario only illustrates the first of these issues).

The answer to the first question is ioslation level. This is the definition of the visibility of uncommmitted transactions across sessions. The ANSI standard specifies four levels:

  • SERIALIZABLE: no changes from another session are ever visible.
  • REPEATABLE READ: phantom reads allowed, that is the same query executed twice may return different results.
  • READ COMMITTED: only changes which have been committed by another session are visible.
  • READ UNCOMMITTED: diryt readsallowed, that is uncommitted changes from one session are visible in another.

Different flavours or database implement these in different fashions, and not all databases support all of them. For instance, Oracle only supports READ COMMITTED and SERIALIZABLE, and it implements SERIALIZABLE as a snapsot (i.e. it is a read-only transaction). However, it uses multiversion concurrency control to prevent non-repeatable reads in READ COMMITTED transactions.

So, coming back to your question, the answer is: set the appropriate Isolation Level. What the appropriate level is depends on what levels your database supports, and what behaviour you wish to happen. Probably you want READ COMMITTED or SERIALIZABLE, that is you want your transactions to proceed on the basis of data values being consistent with the start of the transaction.

As to the other matter, the answer is simpler: transactions must issue locks on tables or preferably just the required rows, before they start to update them. This ensures that the transaction can proceed to change those values without causing a deadlock. This is called pessimistic locking. It is not possible in applications which use connection pooling (i.e. most web-based applications), and the situation there is much gnarlier.

APC