Я хочу обновить строку с помощью цикла while ниже:
void update(long step){
while(true){
long excepted = mapper.queryMaxId("test");
if(mapper.updateMaxId("test",excepted,excepted+step)>0)
break;
}
}
public interface Mapper {
@Select("select max_id from t_agr_sequence where agr_biz_code=#{biz}")
long queryMaxId(@Param("biz") String biz);
@Update({"update t_agr_sequence set max_id=#{actual} where agr_biz_code=#{biz} and max_id=#{excepted}"})
int updateMaxId(@Param("biz") String biz, @Param("excepted") Long excepted, @Param("actual") Long actual);
}
Таблица и индекс показаны ниже:
CREATE TABLE t_agr_sequence (
agr_biz_code varchar(64) NOT NULL ,
max_id bigint(20) NOT NULL ,
PRIMARY KEY (agr_biz_code),
KEY t_agr_sequence_agr_biz_code_max_id_index (agr_biz_code,max_id)
) ENGINE=InnoDB
Я, кроме mysql5.7, использую индекс t_agr_sequence_agr_biz_code_max_id_index
чтобы определить, соответствует ли предложение WHERE, подобно тому, как это делает java-CAS, если предложение WHERE не соответствует, оператор немедленно возвращает 0, строка не заблокирована
Однако в действительности MySQL использует agr_biz_code
индекс первичного ключаи подождите, пока другие потоки освободят строку, затем получите значение max_id
, чтобы определить, соответствует ли предложение WHERE, что не в стиле CAS
.Большое спасибо!
нажмите, чтобы просмотреть план выполнения mysql