Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重用准备好的语句、事务和连接池_Java_Mysql_Transactions_Prepared Statement_Connection Pooling - Fatal编程技术网

Java 重用准备好的语句、事务和连接池

Java 重用准备好的语句、事务和连接池,java,mysql,transactions,prepared-statement,connection-pooling,Java,Mysql,Transactions,Prepared Statement,Connection Pooling,我正在做一个学校项目,在这个项目中,我的团队必须确保数据的一致性和完整性,并提高交易网站的性能。该网站是用JSP和JAVA编写的。我们还在项目中使用MySQL及其ndb集群 首先,我用100、175和250个虚拟用户的负载测试对准备好的语句进行了实验。结果表明,重用准备好的语句可以提高响应时间和吞吐量。通过改进,我的意思是平均响应时间减少,最大吞吐量增加 其次,我还使用连接池对100、175和250个虚拟用户进行了相同的负载测试。同样,结果显示性能有所改善。只是一个附加信息,我使用c3p0作为连

我正在做一个学校项目,在这个项目中,我的团队必须确保数据的一致性和完整性,并提高交易网站的性能。该网站是用JSP和JAVA编写的。我们还在项目中使用MySQL及其ndb集群

首先,我用100、175和250个虚拟用户的负载测试对准备好的语句进行了实验。结果表明,重用准备好的语句可以提高响应时间和吞吐量。通过改进,我的意思是平均响应时间减少,最大吞吐量增加

其次,我还使用连接池对100、175和250个虚拟用户进行了相同的负载测试。同样,结果显示性能有所改善。只是一个附加信息,我使用c3p0作为连接池

根据这些结果,我计划在交易网站上使用准备好的报表和连接池。同时,我们还将使用事务来确保数据的一致性和完整性

目前,我实现预置语句和事务的方式如下:

public class ExchangeBean {
private PreparedStatement psSelectFromBuy = null;
private PreparedStatement psSelectFromSell = null;
private PreparedStatement psInsertBuy = null;
private PreparedStatement psInsertSell = null;
private Connection tranDbConnection = null;

public ExchangeBean() {
    reusePreparedStatements();
}

public void reusePreparedStatements() {
    tranDbConnection = DbBean.getDBConnection();
    dbConnection.setAutoCommit(false);


    try {
        psSelectFromBuy = dbConnection.prepareStatement("SELECT * FROM buy WHERE stock = ?" FOR UPDATE);
        psSelectFromSell = dbConnection.prepareStatement("SELECT * FROM sell WHERE stock = ?" FOR UPDATE);
        psInsertBuy = tranDbConnection.prepareStatement("INSERT INTO buy (userid, date, price, stock) VALUES (?, ?, ?, ?)")
        psInsertSell = tranDbConnection.prepareStatement("INSERT INTO sell (userid, date, price, stock) VALUES (?, ?, ?, ?)");
    } catch (Exception e) {
    }
}

public boolean buy(//some parameters) {
    try {
        selectFromBuy(); //a method that contains psSelectFromBuy
        psInsertBuy.clearParameters();
        psInsertBuy.setInt(1, buy.getUserId());
        psInsertBuy.setLong(2, buy.getDate().getTime());
        psInsertBuy.setInt(3, buy.getPrice());
        psInsertBuy.setString(4, buy.getStock());
        psInsertBuy.executeUpdate();

        //some other codes
        psInsertBuy.commit();
    } catch (Exception e) {
        dbConnection.rollback();
    }
}

public boolean sell(//some parameters) {
    try {
        selectFromSell(); //a method that contains psSelectFromSell
        psInsertSell.clearParameters();
        psInsertSell.setInt(1, sell.getUserId());
        psInsertSell.setLong(2, sell.getDate().getTime());
        psInsertSell.setInt(3, sell.getPrice());
        psInsertSell.setString(4, sell.getStock());
        psInsertSell.executeUpdate();

        //some other codes
        psInsertSell.commit();
    } catch (Exception e) {
        dbConnection.rollback();
    }
}
}
注意:为了简洁起见,此代码示例不完整;相当多的代码和逻辑不在其中

所以基本上,我的方法是将准备好的语句声明为类变量,然后在第一次调用类时实例化它们

问题

  • 我的方法正确吗?我觉得这并不完全正确,因为我所有准备好的陈述都与一个连接有关。我担心如果多个用户同时尝试购买和销售,可能会出现问题,因为只使用了一个连接。但是,我不能关闭连接,否则我准备的报表将在每次交易后关闭,因此不会重复使用。此外,当我提交时,事务中涉及的所有准备好的语句都应该一起提交,因此如果我只使用一个连接就更容易了

  • 你对我应该如何使用连接池和准备好的语句和事务有什么建议吗?每次从池中创建连接时,我都会将所有准备好的语句缓存到连接中。当连接用于购买或出售时,方法本身将禁用该连接上的自动提交,并在方法结束时再次启用自动提交。这种方法合适吗?或者我应该有两个连接池(一个用于非事务连接,一个用于事务连接)


  • 谢谢

    不要自己做这件事。你的代码a)不是线程安全的,b)非常硬编码。c3p0支架开箱即用。我建议您在开始使用之前仔细阅读c3p0的整个页面。此外,您应该在尽可能小的范围内从池中获得连接,因为它们是稀缺资源。简而言之,这不是正确的方法。虽然在测试期间重复使用准备好的语句会对性能产生积极影响,但在生产期间很少有显著影响。数据库网络延迟和符合ACID的设置(如)将决定性能。另一方面,连接池总是一个好主意。嗨,Boris,我已经阅读了c3p0关于语句池()的页面,但是有一件事我不确定。如果我之前在这方面准备了一份声明,并且我在同一个连接上重新准备了该声明,那么该连接是否足够聪明,能够知道该声明之前已经准备好,并使用之前准备好的声明?嗨,vanOekel,即使存在使用连接池进行语句池的情况,您仍然建议不要重用准备好的语句吗?