使用java来模拟并发更新计数

时间:2016-02-20 13:37:03

标签: java java-8 java.util.concurrent

我的同事告诉我,在高并发性中,mysql无法正确处理更新,例如

update product set count = count - 1 where id = ? and count > 0;

也许计数小于0,我认为他错了,所以我写了下面的代码来证明这一点。

    int nThreads = 140; //less than max_connections  151 
    ExecutorService pool = Executors.newFixedThreadPool(nThreads);
    CountDownLatch startLatch = new CountDownLatch(nThreads);
    CountDownLatch endLatch = new CountDownLatch(nThreads);

    for (int i = 0; i < nThreads; i++) {
        pool.submit(() -> {
            startLatch.countDown();
            try { startLatch.await(); } catch (Exception e1) { } //waiting for all task is submitted to guarantee concurrency

            String sql = "update t set count = count-1 where id =1 and count>0";
            try {
                Connection connection = DriverManager.getConnection(url, user, password);
                Statement stat = connection.createStatement();
                stat.execute(sql);
                endLatch.countDown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
    endLatch.await(); //waiting for all task is done
    System.out.println("done");
    System.exit(0);

我想知道我上面的代码是否可以正确地模拟高并发?如果可以通过java8简化上面的代码?

1 个答案:

答案 0 :(得分:1)

mysql无法正确更新数据是不对的。

MySql锁定更新记录,直到事务终止,因此如果同一记录上的上一个事务尚未完成,则没有其他线程可以尝试更新它。