With declarative constructs, the programmer, for example, specifies that he wants this section of code to be atomic. He doesn't specify himself how he wants the system to go about implementing the atomicity. With a declarative construct, in fact, the system can implement it however it wants. On the other hand, things like locks are imperative constructs that the programmer can use to tell the system how to implement atomicity. In this example, imperative and declarative constructs present different levels of abstractions to the programmer, and as such, these abstractions may vary in performance.
It is worth noting here, that apart from using different abstractions (lock vs atomic construct) for ensuring mutual exclusion, the two above code snippets will exhibit significantly different performance.
The one on the left that uses locks is fairly fine-grained, in the sense that mutual exclusion is achieved on a per-account basis. The one on the right is coarse-grained, in the sense that a single deposit action will stall all the other deposit actions in the whole bank, since the atomic construct is now protecting the whole method, not each individual account.
Edit: Thanks to a suggestion by doodooloo, I have a realized that this may not entirely be true. If the read and write sets of two concurrent transactions do not overlap, then the two may be done simultaneously and concurrently, if the implementation allows the same.
Atomicity can be implemented using locks. It can also be implemented with transaction memory by redo/undo when contention is detected.
Declarative construct makes me think about the synchronized method in java, or something like atomic in django. Although I don't know anything about how they implement it, I think it will be best to not use the most naive implementation of using a coarse grain implementation. Some research tells me java avoids this by only locking certain variables when they need to be locked, and seems like they utilize the JVM to know when to lock:
@fleventyfive, I don't think the code on the right will necessarily stall all other deposit actions when a single deposit action happens. I guess it depends on the implementation. In the best situation, we can even read a single account and deposit to it at the same time.
@doodooloo I think you are right, I just realized the same thing while going through the slides. If the read and write sets are completely independent of each other, then the same can potentially be done concurrently and simultaneously, if the implements allows it. (I'll update my answer)
@doodooloo, @fleventyfive. That is correct. Two transactions that do not conflict can be executed concurrently.