Let's say that there's an online ticket-shop that has 100 tickets for sell. If there can be many requests that purchase on the tickets at the same time, there's a risk of a race condition, because there can be 2 (or more) requests at the same time trying to buy the last ticket. And if the software counts the tickets already sold, it is possible that the counter will return 99 (so one ticket is left) for two requests coming in at the same time. So there's a risk that the software will sell 101 tickets (instead of only 100 tickets). In most imperative languages you will probably use something like the keyword "synchronized" (e.g. in Java), to make sure, that counting and selling is "an atomic" operation where no other request can come in, before the previous request has finished processing, right?
But, how would you do this in erlang?
I mean there's no "state" in a function, right? And many requests can come in at the same time getting the number 99 from a counter that counts the tickets (e.g. from a db) that are already sold...
So, what's the way to go in erlang?
1条答案
按热度按时间slhcrj9b1#
Atomic operations in Erlang
Erlang processes do not share their memory, so there's no need to syncrhonize access to each process' memory.
ETS , which allow shared access, have ACID properties in most methods, e.g. ets:update_counter/3
Also, since using ETS only for a counter has a lot of overhead, a more low-level interface for shared atomic integers was provided in OTP21
Way to go (this is subjetive)
Usually the way to go is start using a single process (or a pool of them), leveraging the actor model + message passing to provide atomicity. Since a process is responsible for its own memory, there are no race conditions within itself. In your example, this would mean having a process for each shop and the clients interact with them.
Most often than not this is enough (preemptive scheduling/domain splitting makes wonders), but if it isn't, you explore ETS/atomics-based solutions (atomic operations are not the only interesting qualities about ETS and atomics, they have other uses too)
External state
I have deliberately omitted any reference to an "external" state because there you start having to deal with the real world: Multiple nodes, crashing nodes, network splits... and "synchronized" does not solve you problem there.
Syncrhonizing distributed states requires way more work, sometimes the complexity is not worth it, sometimes this complexity is shifted to another system, such as a DB.