My web application (Point of Sale) handles sales on multiple branches. Each sale has a unique integer ID. Some sale ID on branch 1 is n, then the next sale on branch 2 is n+1.
When a branch looses internet connectivity, I save the sale information on the browser internal database, where the sale ID is the last sale ID plus one. When connectivity is restored I send that in开发者_Python百科fo to the server and then store it in the real database.
Nightmare happens when two or more branches loose internet connectivity. Because when they make a sale offline and internet comes back on, the server will receive two sales with the same ID, which is horrible because the customer ticket has already been printed !
My plan for now, is to make each sale ID a mix from the branch ID and that branch actual sale number. So branch 1 sale ID would be 1-1, and the next sale from branch 2 would be 2-1. Sounds good until a brach has two points of sale, which is not the case, but it isn't very future proof.
What do you think is the best approach ? Is there a better way of doing this ?
The only truly safe way to avoid ID collisions on a single ID is for the server to always allocated the IDs. If the POS goes offline, then you may want to allocate local and temporary IDs for recording the sale locally and then when the POS comes back online, you fetch real IDs from the server and modify the local IDs to be real IDs before sending the transactions. I had a system once that used negative numbers to denote client-created IDs and positive numbers for server-create IDs. When the server received a negative ID, it would change it to a uniquely created server ID and return that ID to the client so the client could update it's database with the real transaction ID.
If you want/need client-defined IDs that are globally unique, then each POS client needs a server-assigned uniqueID that can be part of a multi-part compound ID. Then, each client can just maintain it's own counter that, when combined with it's unique client-ID is always a globally unique ID. It's an extension of your branchID concept except it's a clientID that is uniquely assigned to every client so you can have multiple POS clients at each branch. Assigning a clientID can either be done manually at client setup time or it can be done more dynamically by asking the server for a unique clientID during some setup or intialization process.
Which technique like this is most practical for you depends on a lot more of your system than you've describe here so you'll either have to pick based on your knowledge of that or describe more about how your system works for us to be able to help more.
Ideally, each point of sale has its own ID. For example, I used to work for an international retail chain (will not name it here), which had thousands of branches around the world and up to 15 points of sale in each branch. Each POS had its own ID allocated to it - and it used this ID when authenticating to the back-end system.
If this is the case with your setup, then instead of the branch ID you should use the POS ID. This way, if you have multiple POS in the same branch, you pre-pend the POS ID to the transaction ID.
A compound key as you described is a good solution to this problem. I tend to use a GUID when I need to avoid key collisions in a distributed situation.
精彩评论