Как выполнить настоящее обновление в стиле CAS в Mysql? - PullRequest
0 голосов
/ 17 января 2019

Я хочу обновить строку с помощью цикла 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

...