It took me several days to find the bug.
I got a table like this
TABLE t {uint64_t key, name player1, name player2, uint64_t status};
When the contract received the specific action, it will go through the table to find if there is a row which status == 1
and player2 is empty, if not exist, it will emplace one. Now it has one row like this
{"key" : 1, "player1" : "bob", "player2" : "", "status" : 1}
When next player send the action, he will find the row above and modify the player2 and status. It supposed to be like this.
{"key" : 1, "player1" : "bob", "player2" : "jack", "status" : 2}
The bug comes when two players send action at the SAME time, they could both find the row that status == 1
and player2 is empty! Then the one who modify the table first will be overwritten by the next one. It will becomes like this, jack was overwritten by tom.
{"key" : 1, "player1" : "bob", "player2" : "tom", "status" : 2}
I'm wondering why would two player both find the same row, cause when a player find it he will modify the status to 2. So the next player will never find this row. Even if they both find the row, can we lock the table before we modify it?
I've been suffering from this bug for a long time, does anyone has some good advice?