实际上有10个相同的更新sql,最长的时间是56秒。
这个sql的业务逻辑是,如果用户赢得奖励,应减少该奖励的一个股票。
我认为这是由高并发引起的,只有在这种情况下才存在锁定竞争。然后我决定在我的本地环境中重新生成它,我让很多线程同时执行更新操作,但我无法重现上面的慢sql,下面是我的实验结果:
thred count|100|500|1000|2000
-----|-----|-----|-----|-----
took time(ms)|149|490|1064|1996
即使2000更新sql并发执行,它只需要1996
ms来执行所有。那么如何重新制作这些慢速sql?
我的代码就像这样
@Test
public void test_concurrent_update() throws InterruptedException {
int nThreads = 50; //thread count
ExecutorService pool = Executors.newFixedThreadPool(nThreads);
final CountDownLatch startLatch = new CountDownLatch(nThreads);
final CountDownLatch endLatch = new CountDownLatch(nThreads);
long startTime = System.currentTimeMillis();
for (int i = 0; i < nThreads; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
startLatch.countDown(); // let all threads concurrently execute update operation
try { startLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); }
mapper.updateAwardStock(); // reduce stock by mybatis
endLatch.countDown();
System.out.printf("%s down%n",Thread.currentThread().getName());
}
});
}
endLatch.await(); // wait for all threads are finished executing
long endTime = System.currentTimeMillis();
System.out.printf("%d threads concurrent update stock took time: %d(ms)%n",nThreads,(endTime-startTime));
}
@Update("update award_stock set stock = stock-1 where award_id = 1 and stock>0 limit 1")
void updateAwardStock();