关于jdbc并发问题: 有二个客户端使用人员(用A,B来区分人员)。先后更新oracle库上的某一条数据。因为一些偶然的原因造成A 第一次更新数据的行为一直属于未提交状态。然后 B 再进行更新这条数据操作的时候,于是就造成死锁状态。B不知道是什么原因,于是他多次进行更新数据操作,于是造成大面积死锁现象。 其中我使用了struts的令牌防止刷新页面而造成的重复提交操作。但对于目前这种现象没有任何防治效果。我对jdbc进行了多次断点测试操作。发现是在执行
objStatement = objConnection.prepareStatement(execsql,java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
objStatement.execute();//是在执行这一处代码的时候,就卡主了,不往下面走。
这样就造成了objStatement.close();关闭不了,Connection 也无法commit。然后
finally{}//代码块中关闭连接操作无法完成,链接池中的链接也无法释放。
从而导致了连接池中有效链接全部都非法占用。造成程序速度非常慢。
由于我是用使用jdbc访问数据库层得。暂时没有太好用的思路。跪求高手
给个思路,给个建议。万分感激。分会持续散给大家。求求大家帮帮忙。
objStatement = objConnection.prepareStatement(execsql,java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.ResultSet.CONCUR_READ_ONLY);
objStatement.execute();//是在执行这一处代码的时候,就卡主了,不往下面走。
这样就造成了objStatement.close();关闭不了,Connection 也无法commit。然后
finally{}//代码块中关闭连接操作无法完成,链接池中的链接也无法释放。
从而导致了连接池中有效链接全部都非法占用。造成程序速度非常慢。
由于我是用使用jdbc访问数据库层得。暂时没有太好用的思路。跪求高手
给个思路,给个建议。万分感激。分会持续散给大家。求求大家帮帮忙。
解决方案 »
- 巴巴运动网15集Spring2.5+JPA整合最后去掉DataSoruce配置还是出错!。在线等解决方案
- 怎么用axis2设置soap header 发送请求
- 谁能共享一下传智博客的bbs视频?
- 大家觉得广州国研集团如何?
- hibernate fetch=FetchType.LAZY问题
- struts2配置问题
- 救命啊,为什么下载struts打不开
- 困扰了三天三夜啊!尝试写第一个EJB遇到的问题
- 在JNI用java调用c++定义的函数时(.class与.c文件都已创建好),如何创建共享库文件?
- 推荐一本比较好的EJB入门的书!
- JSF 命令标签<h:commandButton type="button" 疑问
- findByProperty hibernate 急急急
如果原因是:第一次更新数据的行为一直属于未提交状态的话
我建议你加强connection的控制
使用proxy+threadlocal,这样,在proxy关闭,这样应该不会出现共用一个连接而造成死锁
而且更新批量数据是放在一个大事务中然后才一起提交的。我应该这样说明:二套程序使用的是同一个数据库。所有A用程序批量更新账户的余额。
而B是客户,他这个时候去消费。于是就出现我上面所说的情况了。
A用的程序是pb写的。而B用的程序是用java写的。 A程序无法进行优化修改。
所以我想使用jdbc 在更新数据的时候 ,如果当前数据正在处于更新状态当中,就报一个错误提示。我当时想hibernate可能对这一种情况进行了异常处理。所以写了个例子进行测试。
发现一个很有趣的现象。我分别使用了sybase库,和oracle 分别进行测试。sybase库报出了update 异常。 而oracle 则任何异常都没有提示。
我是这样测试的:先把这条记录锁住,不提交。这样就模拟出一直未提交的情况。 sybase提示错误,而oracle就没一点错误信息提示。
另外关于 longintstring 大哥 说 的proxy+threadlocal 方法。希望longintstring 能深入一点。
我也会在继续百度和 google。再次谢谢大家的鼎力支持,我这二天会一刻也不离电脑盘。等待拜读各位神仙的思路。
谢谢!
另外,如果我把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();
}
}
Runnable pinger = new Runnable() {
public void run() {
System.out.println("PING!");//回滚数据,释放池连接
ses.shutdown();
}
};
ses.schedule(pinger, 5, TimeUnit.SECONDS);//5 秒之后开始执行一次。
.... 一些执行sql语句代码。
ses.shutdown();
但是效果也不行。