开发者社区> 问答> 正文

JDBC connection和statement的关系

一个Connection生成多个Statement, 这些Statement可以同时并行的执行吗?

class Runner implements Runnable {
  private Connection conn;
  public Runner(Connection conn) {
    this.conn = conn;
  }
  @Override
  public void run() {
    try {
      Statement stmt = conn.createStatement();
      String sql = "select * from user";
      ResultSet rs = stmt.executeQuery(sql);
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}

Connection conn = MysqlDBUtil.getConnection();
Runner runner = new Runner(conn);
for(int i=0;i<100;i++) {
  Thread t = new Thread(runner);
  t.start();
}

同一个Connection,同时起了100个Statement,测试了一下如果Statement数目比较少似乎能同时执行?如果可以的话,那么一个网站只用开一个Connection,然后每个请求分别建立不同的Statement就可以了吗?个人认为一个Connection下面可以同时执行的Statement是有上限的。
MySQL下,一个connection生成了50000个Statement都不报错,而Oracle会报maximum open cursors exceeded之类的错误:http://stackoverflow.com/questions/12192592/java-sql-sqlexception-ora-01000-maximum-open-cursors-exceeded
根据stackoverflow的解答,Each SELECT statement has a cursor,这个错误的原因还是open statement过多。为什么MySQL没有这样的问题?Oracle的cursor在MySQL中对应什么呢?

展开
收起
蛮大人123 2016-02-28 18:15:44 4365 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    你执行的语句是查询,查询是读锁,100个查询都可以读取相同的数据,因此100个查询之间相互之间是没有影响的。但是对于更新就不是这样了,尤其是涉及到事务的时候。事务是以连接Connection为单位的,在JDBC中,默认autocommit是true,所以每一个SQL语句都是一个事务。当你在同一个连接上,创建不同的Statement的时候,是没法保证事务的ACID特性的,数据不一致就会发生,程序就是错误的。创建Connection是十分耗时的操作,一般情况下,都是使用连接池,比如c3p0,需要Connection的时候就去连接池取。Spring的事务管理是把Connection与当前线程关联起来实现事务。

    2019-07-17 18:49:57
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载