I looked into Erlang in some depth, and found its concurrency ability was due to shared-nothing modules (which smalltalk also has), which I think you refer to with "messaging". Race conditions can still occur, which I guess you include with "not all of them". Plus, in Erlang this was found to not address all concurrency problems, and so a software transactional database is included as standard.
Looking at the details, I don't think general concurrency is a solved problem. Looking at the results, if it was, we'd have much better utilisation of multi-core architectures by now than we do. For example, 32 core x86, clocked ultra-low, for extraordinarily low power consumption.
Actually, another issue is that message passing might work better with cores with their own RAM, so the modules can work independently.
I think there's a huge amount of kool-aid around concurrency "solutions" - functional programming, erlang, and now Go. Because concurrency is so valuable, if Go really does make it trivial, we it should quickly dominate all other languages. But it seems to me that concurrency is still a hard problem.