Anti-heavy watch
1. The problem of preventing table duplication
Another solution to prevent repeated submission of data is to implement an anti-duplication table. The idea of anti-heavy watch is also very simple. First create a table as an anti-duplication table, and at the same time establish a unique index of one or more fields in the table as an anti-duplication field to ensure that there is only one piece of data under concurrent conditions. Insert data into the anti-duplication table before inserting data into the business table. If the insertion fails, it means duplicate data
For the solution to the anti-heavy table, some people may say why not use pessimistic locking. Deadlocks may also occur during the use of pessimistic locks. Pessimistic locking is implemented by locking tables. Suppose now a user A accesses table A (table A is locked), and then tries to access table B; another user B accesses table B (table B is locked), and then tries to access table A. At this time, for user A, since table B has been locked by user B, user A must wait until user B releases table B before he can access it. At the same time, for user B, since table A has been locked by user A, user B must wait until user A releases table A before accessing it. At this point the deadlock has already occurred
2. Solution (select+insert anti-resubmission)
When the amount of concurrency is not high, the realization of idempotence is very simple, and idempotent control can be completed through the idea of select+insert. Before the business is executed, first judge whether it has been operated, if not, execute it, otherwise it is judged as a repeated operation
3. Implement ideas
When accessing concurrently, because the judgment is based on the id, the id value must be guaranteed to be unique when submitted multiple times. The access process is as follows and
the code is as follows:
@Override
@Transactional(rollbackFor = Exception.class)
public String addOrder(Order order) {
order.setCreateTime(new Date());
order.setUpdateTime(new Date());
//查询
Order orderResult = orderMapper.selectByPrimaryKey(order.getId());
Optional<Order> orderOptional = Optional.ofNullable(orderResult);
if (orderOptional.isPresent()) {
return "数据存在";
}
int result = orderMapper.insert(order);
if (result != 1) {
return "失败";
}
return "成功";
}
For the above solution, idempotence control cannot be achieved under concurrency. Through the jemeter test and simulating 50 concurrencies, it can be found that duplicate data has been inserted. Dirty data is generated. To solve this problem, it is very simple. Just add a unique index at the database level. Setting the id as a unique index is also the easiest way to think of it. Once the id is repeated, an exception will occur, which can also be solved by avoiding the occurrence of dirty data. Permanently idempotent. However, this solution cannot be used in the case of sub-database and sub-table. It is only applicable to the case of single table.