Most CPU architectures provide atomic read, write and barrier primitives. Locking is a higher level interface and usually involves use of those atomic primitives.
The point is that once you have these low level guarantees, you can actually implement a good transactional system on top.
Historically what we got from storage in terms of guarantees was just "once you fsync your data will probably persist if you did it very carefully but not always".