Message passing doesn't help either. What many programmers don't realize that synchronization problems (deadlocks) are _not_ the consequence of using mutexes or other primitives per se. They're the result of synchronization itself.
Message passing can be asynchronous, but on some level, the system might have to synchronize certain operations. If you implement a financial system, you'll certainly have to synchronize stuff even if you're using asychronous message passing to implement it -- you will simply implement synchronicity on the top of an asychronous infrastructure.
And when operations start to depend on each other, then you _have_ to think about potential deadlocks, race conditions, etc.
Basically there isn't anything that solves this for you. STM is somewhat different as the danger is not deadlocks but starvation, etc.