objStatement = objConnection.prepareStatement(execsql,java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
objStatement.execute();//是在执行这一处代码的时候,就卡主了,不往下面走。
这样就造成了objStatement.close();关闭不了,Connection 也无法commit。然后
finally{}//代码块中关闭连接操作无法完成,链接池中的链接也无法释放。
从而导致了连接池中有效链接全部都非法占用。造成程序速度非常慢。
由于我是用使用jdbc访问数据库层得。暂时没有太好用的思路。跪求高手
给个思路,给个建议。万分感激。分会持续散给大家。求求大家帮帮忙。
14 个解决方案
#1
我想说第一次更新数据的行为一直属于未提交状态
为什么不控制下呢?有什么原因吗?
为什么不控制下呢?有什么原因吗?
#2
不知道我理解你的意思对不对
如果原因是:第一次更新数据的行为一直属于未提交状态
的话
我建议你加强connection的控制
使用proxy+threadlocal,这样,在proxy关闭,这样应该不会出现共用一个连接而造成死锁
如果原因是:第一次更新数据的行为一直属于未提交状态
的话
我建议你加强connection的控制
使用proxy+threadlocal,这样,在proxy关闭,这样应该不会出现共用一个连接而造成死锁
#3
还“急”?
发了个帖子,就没人影了!
发了个帖子,就没人影了!
#4
哈,给位大大谅解谅解。是在是家里有事情急着处理。怠慢了。在此向给位路过的大大致歉!
第一次更新数据的行为,是大批量的更新数据,这个过程一般都会是在10分钟到30分钟之间。
而且更新批量数据是放在一个大事务中然后才一起提交的。
我应该这样说明:二套程序使用的是同一个数据库。所有A用程序批量更新账户的余额。
而B是客户,他这个时候去消费。于是就出现我上面所说的情况了。
A用的程序是pb写的。而B用的程序是用java写的。 A程序无法进行优化修改。
所以我想使用jdbc 在更新数据的时候 ,如果当前数据正在处于更新状态当中,就报一个错误提示。
我当时想hibernate可能对这一种情况进行了异常处理。所以写了个例子进行测试。
发现一个很有趣的现象。我分别使用了sybase库,和oracle 分别进行测试。sybase库报出了update 异常。 而oracle 则任何异常都没有提示。
我是这样测试的:先把这条记录锁住,不提交。这样就模拟出一直未提交的情况。 sybase提示错误,而oracle就没一点错误信息提示。
另外关于 longintstring 大哥 说 的proxy+threadlocal 方法。希望longintstring 能深入一点。
我也会在继续百度和 google。
再次谢谢大家的鼎力支持,我这二天会一刻也不离电脑盘。等待拜读各位神仙的思路。
谢谢!
第一次更新数据的行为,是大批量的更新数据,这个过程一般都会是在10分钟到30分钟之间。
而且更新批量数据是放在一个大事务中然后才一起提交的。
我应该这样说明:二套程序使用的是同一个数据库。所有A用程序批量更新账户的余额。
而B是客户,他这个时候去消费。于是就出现我上面所说的情况了。
A用的程序是pb写的。而B用的程序是用java写的。 A程序无法进行优化修改。
所以我想使用jdbc 在更新数据的时候 ,如果当前数据正在处于更新状态当中,就报一个错误提示。
我当时想hibernate可能对这一种情况进行了异常处理。所以写了个例子进行测试。
发现一个很有趣的现象。我分别使用了sybase库,和oracle 分别进行测试。sybase库报出了update 异常。 而oracle 则任何异常都没有提示。
我是这样测试的:先把这条记录锁住,不提交。这样就模拟出一直未提交的情况。 sybase提示错误,而oracle就没一点错误信息提示。
另外关于 longintstring 大哥 说 的proxy+threadlocal 方法。希望longintstring 能深入一点。
我也会在继续百度和 google。
再次谢谢大家的鼎力支持,我这二天会一刻也不离电脑盘。等待拜读各位神仙的思路。
谢谢!
#5
#6
顶~望高手正解~
#7
项项更健康...
#8
java.util.concurrent 我查了一些资料,发现 jdk1.5版本后提供了 这个并发库。发觉里面看起来还是有很好用的api,用来处理阻塞队列,和设置超时。 目前正在写例子测试中,还不知道能不能满足我想要的结果。如果各位路过的神仙曾经有使用过这个库的经验。希望赐教,给个看法,或者一些例子什么的。给小弟一个启发。知道分少了很多。但是还是会多赚点分,继续散给大家。
另外,如果我把Connection的事务提到 TRANSACTION_REPEATABLE_READ 隔离级别,但是写了例子。也没有作用。代码如下:
另外,如果我把Connection的事务提到 TRANSACTION_REPEATABLE_READ 隔离级别,但是写了例子。也没有作用。代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Ping{
public static void runJdbc() {
String url="jdbc:oracle:thin:@127.0.0.1:1521:cftest";
String user="anning";
String password="cfsi_any_user08";
Connection objConnection = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("chuangjian");
PreparedStatement objStatement = null;
objConnection = DriverManager.getConnection(url, user,password);
objConnection.setTransactionIsolation(objConnection.TRANSACTION_SERIALIZABLE);
String sql="UPDATE KC04 SET AKC085=? WHERE AAC001=? ";
objStatement=objConnection.prepareStatement(sql);
objStatement.setString(1, "11");
objStatement.setString(2, "1504011003658200000");
System.out.println("chuangjian0");
objStatement.execute();
System.out.println("chuangjian1");
objStatement.close();
objConnection.commit();
System.out.println("chuangjian2");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
objConnection.close();
} catch (SQLException e) {
}
}
}
public static void main(String[] args)
{
runJdbc();
}
}
#9
我在cmd 下 用 plsql 命令连上oracle 库,然后写一个update语句,执行这条记录之后没有commit;
然后,我再执行上面的代码,发现到objStatement.execute(); 就卡主,没有往下走。
我就像达到 如果在 runJdbc方法内 执行的时间超过我设定的限制时间,那么就回滚数据并
执行关闭数据库连接。 我使用了 java.util.concurrent 包下的 ScheduledExecutorService接口先:final ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable pinger = new Runnable() {
public void run() {
System.out.println("PING!");//回滚数据,释放池连接
ses.shutdown();
}
};
ses.schedule(pinger, 5, TimeUnit.SECONDS);//5 秒之后开始执行一次。
.... 一些执行sql语句代码。
ses.shutdown();
但是效果也不行。
然后,我再执行上面的代码,发现到objStatement.execute(); 就卡主,没有往下走。
我就像达到 如果在 runJdbc方法内 执行的时间超过我设定的限制时间,那么就回滚数据并
执行关闭数据库连接。 我使用了 java.util.concurrent 包下的 ScheduledExecutorService接口先:final ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable pinger = new Runnable() {
public void run() {
System.out.println("PING!");//回滚数据,释放池连接
ses.shutdown();
}
};
ses.schedule(pinger, 5, TimeUnit.SECONDS);//5 秒之后开始执行一次。
.... 一些执行sql语句代码。
ses.shutdown();
但是效果也不行。
#10
Statement, PreparedStatement 有个 setQueryTimeout 方法可以设置超时时间。
最主要的是,你那个事务要挂起二三十分钟,这势必得锁住啊!
最主要的是,你那个事务要挂起二三十分钟,这势必得锁住啊!
#11
是啊,但是那一块的业务的处理,暂时目前无法处理优化。。所以 就只能通过这个笨办法去 实现。
其实,我最希望的是,有一个异常机制最好了。 向sybase库,如果sybase库要更新的这条记录,是锁住状态,那么,hibernate的异常机制,直接就报一个 update 失败的异常。
这样通过框架 就能控制异常了。 而现在 oracle 居然没一点反应,很费解
其实,我最希望的是,有一个异常机制最好了。 向sybase库,如果sybase库要更新的这条记录,是锁住状态,那么,hibernate的异常机制,直接就报一个 update 失败的异常。
这样通过框架 就能控制异常了。 而现在 oracle 居然没一点反应,很费解
#12
衷心谢谢 ()火龙果() 大大 给出的建议。我试了。效果挺好的。比我自己这二天研究使用 jdk并发库所使用的例子强多了。 衷心感谢你 以及 各位路过的神仙大大。 小弟在此拜谢。
#13
火龙果,这个一般设置为多长时间?60s怎么样?
#14
刚引用错了,火龙果,这个一般设置为多长时间?60s怎么样?
#1
我想说第一次更新数据的行为一直属于未提交状态
为什么不控制下呢?有什么原因吗?
为什么不控制下呢?有什么原因吗?
#2
不知道我理解你的意思对不对
如果原因是:第一次更新数据的行为一直属于未提交状态
的话
我建议你加强connection的控制
使用proxy+threadlocal,这样,在proxy关闭,这样应该不会出现共用一个连接而造成死锁
如果原因是:第一次更新数据的行为一直属于未提交状态
的话
我建议你加强connection的控制
使用proxy+threadlocal,这样,在proxy关闭,这样应该不会出现共用一个连接而造成死锁
#3
还“急”?
发了个帖子,就没人影了!
发了个帖子,就没人影了!
#4
哈,给位大大谅解谅解。是在是家里有事情急着处理。怠慢了。在此向给位路过的大大致歉!
第一次更新数据的行为,是大批量的更新数据,这个过程一般都会是在10分钟到30分钟之间。
而且更新批量数据是放在一个大事务中然后才一起提交的。
我应该这样说明:二套程序使用的是同一个数据库。所有A用程序批量更新账户的余额。
而B是客户,他这个时候去消费。于是就出现我上面所说的情况了。
A用的程序是pb写的。而B用的程序是用java写的。 A程序无法进行优化修改。
所以我想使用jdbc 在更新数据的时候 ,如果当前数据正在处于更新状态当中,就报一个错误提示。
我当时想hibernate可能对这一种情况进行了异常处理。所以写了个例子进行测试。
发现一个很有趣的现象。我分别使用了sybase库,和oracle 分别进行测试。sybase库报出了update 异常。 而oracle 则任何异常都没有提示。
我是这样测试的:先把这条记录锁住,不提交。这样就模拟出一直未提交的情况。 sybase提示错误,而oracle就没一点错误信息提示。
另外关于 longintstring 大哥 说 的proxy+threadlocal 方法。希望longintstring 能深入一点。
我也会在继续百度和 google。
再次谢谢大家的鼎力支持,我这二天会一刻也不离电脑盘。等待拜读各位神仙的思路。
谢谢!
第一次更新数据的行为,是大批量的更新数据,这个过程一般都会是在10分钟到30分钟之间。
而且更新批量数据是放在一个大事务中然后才一起提交的。
我应该这样说明:二套程序使用的是同一个数据库。所有A用程序批量更新账户的余额。
而B是客户,他这个时候去消费。于是就出现我上面所说的情况了。
A用的程序是pb写的。而B用的程序是用java写的。 A程序无法进行优化修改。
所以我想使用jdbc 在更新数据的时候 ,如果当前数据正在处于更新状态当中,就报一个错误提示。
我当时想hibernate可能对这一种情况进行了异常处理。所以写了个例子进行测试。
发现一个很有趣的现象。我分别使用了sybase库,和oracle 分别进行测试。sybase库报出了update 异常。 而oracle 则任何异常都没有提示。
我是这样测试的:先把这条记录锁住,不提交。这样就模拟出一直未提交的情况。 sybase提示错误,而oracle就没一点错误信息提示。
另外关于 longintstring 大哥 说 的proxy+threadlocal 方法。希望longintstring 能深入一点。
我也会在继续百度和 google。
再次谢谢大家的鼎力支持,我这二天会一刻也不离电脑盘。等待拜读各位神仙的思路。
谢谢!
#5
#6
顶~望高手正解~
#7
项项更健康...
#8
java.util.concurrent 我查了一些资料,发现 jdk1.5版本后提供了 这个并发库。发觉里面看起来还是有很好用的api,用来处理阻塞队列,和设置超时。 目前正在写例子测试中,还不知道能不能满足我想要的结果。如果各位路过的神仙曾经有使用过这个库的经验。希望赐教,给个看法,或者一些例子什么的。给小弟一个启发。知道分少了很多。但是还是会多赚点分,继续散给大家。
另外,如果我把Connection的事务提到 TRANSACTION_REPEATABLE_READ 隔离级别,但是写了例子。也没有作用。代码如下:
另外,如果我把Connection的事务提到 TRANSACTION_REPEATABLE_READ 隔离级别,但是写了例子。也没有作用。代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Ping{
public static void runJdbc() {
String url="jdbc:oracle:thin:@127.0.0.1:1521:cftest";
String user="anning";
String password="cfsi_any_user08";
Connection objConnection = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("chuangjian");
PreparedStatement objStatement = null;
objConnection = DriverManager.getConnection(url, user,password);
objConnection.setTransactionIsolation(objConnection.TRANSACTION_SERIALIZABLE);
String sql="UPDATE KC04 SET AKC085=? WHERE AAC001=? ";
objStatement=objConnection.prepareStatement(sql);
objStatement.setString(1, "11");
objStatement.setString(2, "1504011003658200000");
System.out.println("chuangjian0");
objStatement.execute();
System.out.println("chuangjian1");
objStatement.close();
objConnection.commit();
System.out.println("chuangjian2");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
objConnection.close();
} catch (SQLException e) {
}
}
}
public static void main(String[] args)
{
runJdbc();
}
}
#9
我在cmd 下 用 plsql 命令连上oracle 库,然后写一个update语句,执行这条记录之后没有commit;
然后,我再执行上面的代码,发现到objStatement.execute(); 就卡主,没有往下走。
我就像达到 如果在 runJdbc方法内 执行的时间超过我设定的限制时间,那么就回滚数据并
执行关闭数据库连接。 我使用了 java.util.concurrent 包下的 ScheduledExecutorService接口先:final ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable pinger = new Runnable() {
public void run() {
System.out.println("PING!");//回滚数据,释放池连接
ses.shutdown();
}
};
ses.schedule(pinger, 5, TimeUnit.SECONDS);//5 秒之后开始执行一次。
.... 一些执行sql语句代码。
ses.shutdown();
但是效果也不行。
然后,我再执行上面的代码,发现到objStatement.execute(); 就卡主,没有往下走。
我就像达到 如果在 runJdbc方法内 执行的时间超过我设定的限制时间,那么就回滚数据并
执行关闭数据库连接。 我使用了 java.util.concurrent 包下的 ScheduledExecutorService接口先:final ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable pinger = new Runnable() {
public void run() {
System.out.println("PING!");//回滚数据,释放池连接
ses.shutdown();
}
};
ses.schedule(pinger, 5, TimeUnit.SECONDS);//5 秒之后开始执行一次。
.... 一些执行sql语句代码。
ses.shutdown();
但是效果也不行。
#10
Statement, PreparedStatement 有个 setQueryTimeout 方法可以设置超时时间。
最主要的是,你那个事务要挂起二三十分钟,这势必得锁住啊!
最主要的是,你那个事务要挂起二三十分钟,这势必得锁住啊!
#11
是啊,但是那一块的业务的处理,暂时目前无法处理优化。。所以 就只能通过这个笨办法去 实现。
其实,我最希望的是,有一个异常机制最好了。 向sybase库,如果sybase库要更新的这条记录,是锁住状态,那么,hibernate的异常机制,直接就报一个 update 失败的异常。
这样通过框架 就能控制异常了。 而现在 oracle 居然没一点反应,很费解
其实,我最希望的是,有一个异常机制最好了。 向sybase库,如果sybase库要更新的这条记录,是锁住状态,那么,hibernate的异常机制,直接就报一个 update 失败的异常。
这样通过框架 就能控制异常了。 而现在 oracle 居然没一点反应,很费解
#12
衷心谢谢 ()火龙果() 大大 给出的建议。我试了。效果挺好的。比我自己这二天研究使用 jdk并发库所使用的例子强多了。 衷心感谢你 以及 各位路过的神仙大大。 小弟在此拜谢。
#13
火龙果,这个一般设置为多长时间?60s怎么样?
#14
刚引用错了,火龙果,这个一般设置为多长时间?60s怎么样?