同是启动三个线程,执行3条SQL语句。线程1:select * from table with (ROWLOCK,UPDLOCK) where ID = '0001'
线程2:select * from table with (ROWLOCK,UPDLOCK) where ID = '0001' (与线程1完全相同)
线程3:select * from table with (ROWLOCK,UPDLOCK) where ID = '0002' (ID不同的记录)1。使用Statement来执行的代买如下:
conn.setAutoCommit(false);
stm = conn.CreateStatement(strSql);
stm.executeQuery();
sleep(5000); 重点是这里只有线程1休眠5秒钟,线程2,3不执行这句。
conn.commit();  执行结果是:线程1执行后,因为休眠5秒钟而没有马上commit,导致线程2也等待了5秒钟。
              线程3因为读取不同的记录 所以没有等待5秒钟立刻就执行完了。
2。使用prepareStatement来执行的代买如下:
conn.setAutoCommit(false);
stm = conn.prepareStatement(strSql);
stm.executeQuery();
sleep(5000); 重点是这里只有线程1休眠5秒钟,线程2,3不执行这句。
conn.commit();   执行结果是:线程1执行后,因为休眠5秒钟而没有马上commit,导致线程2也等待了5秒钟。
               线程3这回也等待了5秒钟才执行完。
为什么会这样,哪位高人知道,请赐教。另外用SQLServer的管理器执行的话结果和Statement是一样的。即线程3执行的SQL文不会等待。

解决方案 »

  1.   

    没有测试这样的问题。标记一下。但我想应该和 JDBC 的实现有关。
      

  2.   

    Statement是一次处理一条语句的,这样只要这条语句没有问题就可以执行了。
    prepareStatement是一次处理一堆语句的,要把这些语句按顺序一起执行。
    个人理解仅供参考!
      

  3.   

    prepareStatement 对oracle预编译的,但是如果SQL写死的常量,效果可能还不如Statement。
    但是若prepareStatement中的SQL带变量方式,比Statement的效率要提升十倍多吧
      

  4.   

    可能跟with (ROWLOCK,UPDLOCK) 这个有关 我觉得
    把with (ROWLOCK,UPDLOCK)删除再试试呢
      

  5.   

    在JDBC的连接字符串中加入sendStringParametersAsUnicode = false后,prepareStatement的运行结果居然就变成了和Statement一样的结构了。但不知道为什么会跟这个属性有关系。有人能赐教一下吗?String url = "jdbc:sqlserver://" + ip + ";databasename=db;sendStringParametersAsUnicode = false";