Atomicity: All operations either occur or fail and are treated as single instructions.
Consistency: Any rules set (cascades, indexes, triggers) are correctly executed.
Isolation: Concurrent behavior shall be the same as sequential behavior.
Durability: Changes are persisted and shall not be lost, even with a DMBS crash.
Caveat:
In the banking scenario, each access (GetBalance, SetNewBalanceToDB) follows ACID, but the database has no knowledge (or control) over the additional logic.
Databases provide notions additional mechanisms to enforce ACID with macro operations.
At Commit(); DB version is acquired.Commit may FAIL if another change took place.
Improper Synchronization
// Globalshared_object_t data;voidupdate_data(char* cookie,pthread_mutex_t* mutex) {pthread_mutex_lock(mutex);// Manipulate global data objectpthread_mutex_unlock(mutex);}
Direct solution:
Protect changes with a mutex.
Developer assumes lock/unlock always work.
CWE-362 – Race Condition – Isolated Ops
X86_64: i++ with gcc
add DWORD PTR [rbp-4], 1
X86_64: i++ with clang
mov edi, dword ptr [rbp - 8]
add edi, 1
mov dword ptr [rbp - 8], edi
ARM: i++
ldr r3, [fp, #-8]
add r3, r3, #1
str r3, [fp, #-8]
Developer thinks: i++ is a single operation.
In reality... it depends, and varies with the architecture.
Still (generic behavior).
Value of “i" must be available (previous logic).
Value must be fetched from RAM to Cache.
Page must be addressed and then loaded.
MMUs and other systems are used.
Value must be fetched from cache to Register.
Register as to be increased.
Result must be stored in Cache.
Result shall be committed to RAM.
CWE-362 - Improper Synchronization
The following function attempts to acquire a lock to perform operations on a shared resource.
The code does not check the value returned by pthread_mutex_lock() for errors.
If pthread_mutex_lock() cannot acquire the mutex for any reason, the function may introduce a race condition into the program and result in undefined behavior.