使用java模拟并发更新计数

使用java模拟并发更新计数,java,java-8,java.util.concurrent,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(nT

我的同事告诉我,在高并发情况下,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);
int=140//小于最大连接数151
ExecutorService池=Executors.newFixedThreadPool(nThreads);
CountDownLatch STARTATCH=新的CountDownLatch(n次读取);
CountDownLatch endLatch=新的CountDownLatch(n次读取);
对于(int i=0;i{
倒计时();
尝试{startatch.await();}catch(异常e1){}//等待提交所有任务以保证并发性
String sql=“update t set count=count-1,其中id=1,count>0”;
试一试{
Connection Connection=DriverManager.getConnection(url、用户、密码);
Statement stat=connection.createStatement();
stat.execute(sql);
endlack.countDown();
}捕获(例外e){
e、 printStackTrace();
}
});
}
等待()//等待所有任务完成
系统输出打印项次(“完成”);
系统出口(0);

我想知道我上面的代码是否可以正确模拟高并发性?如果可以用java8简化上述代码,mysql不能正确更新数据是不对的


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

谢谢!但是我想知道我的代码是否可以像在现实世界中一样模拟并发更新db,是否可以通过采用java8语法简化我的代码。在等待闩锁让实际执行尽可能并发运行之前,您可以打开连接并使用
prepareStatement
。不要忘记
commit
和适当的资源关闭,否则,更新丢失不是数据库的错…