preface
Let’s talk about the first way to modify idempotency
Database idempotency
Suppose we have a user table and insert a record into it every time someone registers. We want to ensure that changes are idempotent. Preliminary ideas can be two: The first method is to query the email in the database. If the email is not available, it is like inserting a new email into the database. The second method is to delete the record of the email and then insert a new email.
Let’s assume that the query (delete) operation and the insert operation are not in the same transaction.
Delete is also a similar situation, so the simple search (delete) and then plug way can not solve this problem.
If the query (delete) operation and insert are not in the same transaction, it is possible to solve the problem in a transaction.
This brings us to the transaction isolation levels, which are read uncommitted, read committed, repeatable read, and serializable. There have been many articles about these four isolation levels. Serializable addresses these problems but has poor performance and concurrency, and applications are too vulnerable to rely heavily on database isolation levels.
Optimistic locking scheme
For both performance and security we can add a unique key to the table when it is being built:
create unique index user_email_uindex on user (email);
Copy the code
The situation would look like this:
For example, in some scenarios, there is no obvious unique key such as mailbox, so you can manually generate one. For example, when the user opens the form page, a UID will be generated and returned to the front end. The front end’s repeated clicking will not lead to repetition, and the unified timestamp or version number can be used to prevent unexpected effects caused by concurrent modification
But there are drawbacks
- Has pressure to the database, especially the possibility of conflicts will lead to a large number of transaction rollback, performance pressure is bigger, actually a bit like to define a method, enter a string, to judge whether an integer, you can directly call transformation method, throw an exception is returned is not the integer, Java specification does not recommend so operation, Because trycatch is too expensive, it is best to determine whether the trycatch conforms to the regular case, etc., and then do the conversion.
- The scenario is limited, and the required database supports optimistic locking. Some operations or non-relational databases do not support optimistic locking, so this method cannot be used
- Business complicated optimistic locking scenario is more complex, ABA issues, such as the above example for an instant, for the first time, click the transaction has been registered went up, and the cancellation of the second click on the transaction was registered on again,,, or business logic is complex, not only is to insert a table, also need to send an email, The role configuration needs to be added, and there are many issues to consider when using optimistic locks, otherwise it will lead to multiple emails and other issues
After talking about the disadvantages of optimistic locking, we will discuss other ways to ensure idempotency and eliminate the problems of optimistic locking as much as possible.
WX Codog code dog: