テーブル内の行を更新するための複数のスレッドを持つスケジューラがあります。私は "for update skip locked"を使用しようとしていますが、何らかの理由で、次のunclaimed行を見つけるのではなく、すべてのスレッドが同じものを選択して更新します。 私は、 "id"と "counter"カラムを持つテーブル "counter"を持っています。Spring JDBCを使用したPostgres "SKIP LOCKED"
CounterRepository.javaが
@Repository
public class CounterRepository {
private final JdbcTemplate jdbc;
public CounterRepository(JdbcTemplate jdbc) {this.jdbc = jdbc;}
@Transactional
void update() {
Integer id = jdbc.queryForObject("SELECT id FROM counter ORDER BY counter LIMIT 1 FOR UPDATE SKIP LOCKED;", Integer.class);
Integer counter = jdbc.queryForObject("SELECT counter FROM counter WHERE id = ?", Integer.class, id);
jdbc.update("UPDATE counter set counter = ? WHERE id = ?", 5 - counter, id);
}
}
DbAsyncUpdateApplication.java
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class DbAsyncUpdateApplication {
@Bean(name = "threadPoolTaskExecutor")
public ScheduledExecutorService taskScheduler() throws InterruptedException {
return Executors.newScheduledThreadPool(5);
}
public static void main(String[] args) {
SpringApplication.run(DbAsyncUpdateApplication.class, args);
}
}
Scheduler.java
@Service
public class Scheduler {
private final CounterRepository repository;
public Scheduler(CounterRepository repository) {this.repository = repository;}
@Scheduled(fixedRate = 1000)
public void start() {
repository.update();
}
}
どのトランザクションレベルを使用していますか?ロジックが動作するためには、行の読み込みロックが必要です。 – Voo
@Vooデフォルトの読み込み済み –
これはなぜうまくいかないのか分かります。 – Voo