讨论一下类设计中数据库链接的使用问题! 大家在程序的设计中一般什么情况下用传入的链接,什么情况直接去链接池里取空闲的链接?有没有什么心得?或者有什么麻烦?欢迎大家来讨论。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 解释:1、方法a和方法b2、方法a要调用方法b现在方法b也可以直接取取链接池里的资源也可以用方法a中已经取出的链接像这种情况对于方法b来说直接用方法a的接力链接应该要好一点,但是如果把所有的类似于b的方法都用他的上一组传入的链接不知道合不合理?我看大多数都是在b里面直接再取一个链接像这种情况的话如果在a里面有多步操作需要回滚时b里因为有新的链接所以会造成阻塞 绝对不建议在程序中多出操作数据库联接。也就是说既不要在b中取出新的联接,更不要将a中的联接传给b正确的方法,应该是在程序中有专门DBAdapter来操作数据库。而不论a还是b都调用它来直接获得所需要的数据 楼上星哥,说的好像很有道理,可是我不太明白.在我和程序中也有专门处理数据库操作的包,不知道是不是你指的DBAdapter,我是把insert update query 等方法都封装起来,需要操作数据库的时候就从连接池里取一个联接然后执行所需的方法,这样也就出现了一种情况:1、比如一个有五步数据操作的过程,其实中每一步都有自己单独的方法,在每步中他们都自己调用连接,这样就存在一个问题,如果中间哪一步出现问题是需要回滚的,但这种情况下回滚不太好弄。2、另外一种方法就是把这五步都写到一个大的函数体内,但会构成一个超大的函数体,再说也不符合面向对象的特性。3、我想这样处理不知道合不合适,就是把这五个函数都使用外层函数的CONN作为参数传入这五个方法这样我就可以在外层实现五步操作的回滚了。不知道楼主指的DBAdapter该怎么理解,能不能给点思路,或资料? 这种情况下可以把数据库相关的东西封装成一个Tansaction对象,然后再执行过程中用这个对象进行传递。总之对数据库的操作要集中在一个地方,而不该分布在不同的地方。 楼上的意思是不是指一个业务开始时调用一个Tansaction对象,然后在该业务的执行过程中始终使用一个连接而通过Tansaction在各个方法中进行传递?最后业务完成后统一执行数据库操作? 没错,这样的话数据库相关操作可以集中在Transaction类中进行,而不会分散在程序的各处。 绝对不能传连接,这么传来传去的也不好管理。只要用一个统一的类就管理连接可以了,如果不用ORM的话,也就是不用hibernate之类的东西了,只用jdbc来实现,你可以参考apache的dbutil包。统一加事务,否则你的程序就是典型的新手上路的程序,实际运行根本不堪一击。 to:mxlmwl(飞星) 嫩说的“统一加事务”很吸引人,我得先查点资料,再来参与讨论,楼上 星哥2 (晕,这年头叫星的人可真多呀:>只能加个2区分了),如果有什么资料可提供参考的话最好能共享一下,分不够可以另开帖加分,其实我觉得传来传去也不太合适。 解释:果然带星的就是不一样,楼上 两位星哥其实我感觉所说的方法是一样的,不知道星哥们是什么意见,且看下面分解代码先:public int delete(int sID) { DataBaseConnection dbc = null; dbc = new DataBaseConnection(); dbc.getConnection(); UserTransaction transaction = sessionContext.getUserTransaction();//获得JTA事务 try { transaction.begin(); //开始JTA事务 dbc.executeUpdate("delete from bylaw where ID=" + sID); dbc.executeUpdate("delete from bylaw _content where ID=" + sID); dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID); transaction.commit(); //提交JTA事务 dbc.close(); return 1; } catch (Exception exc) { try { transaction.rollback();//JTA事务回滚 } catch (Exception ex) { //JTA事务回滚出错处理 ex.printStackTrace(); } exc.printStackTrace(); dbc.close(); return -1; }} 这应该就是"星哥1"所说的transaction ,其实也应该是 "星哥2" 所说的"统一加事务"了现在发现带星的果然不一样 ^_^详见:http://dev.csdn.net/article/43/43272.shtm这种方法的确能解决我的问题,小弟谢楼上客位先,再看两天如果楼下没有反对意见就结帖! 我也有个事务的方法,给大家看看//执行事务处理语句 public boolean runTrans(PreparedStatement [] pst){ boolean b=false; try{ openConnection(); con.setAutoCommit(false); for(int i=0;i<pst.length;i++){ pst[i].executeUpdate(); } con.commit(); b=true; } catch(Exception e){ try{ con.rollback(); e.printStackTrace(); } catch(Exception ex){ ex.printStackTrace(); } } finally{ try{ for(int i=0;i<pst.length;i++){ pst[i].close(); } closeConnection(); } catch(SQLException sqle){ sqle.printStackTrace(); } } return b; } 楼上“wanchao2001(如果可以重来,我还是选择程序员)”兄弟,建议以后回帖时先看帖。这样回答问题即自己宝贵的浪费了时间又赚不到分 :< 又遇到问题了,从sun上下了JTA,打了个JAR包放到工程里面,结果不让 import 从baidu上bai从google上go都没有查到相应的解决方法,为这个问题我都快死了,就为了设计一个合理的程序,楼上帮忙解决一下呀 解释:是不让 import javax.transaction.UserTransaction 这个类,是一个interface 类不知道为什么具体操作如下:1、从sun下了个包2、把打了个javax.jar包放到WEB-INF\lib里面,并在工程里引用这个JAR包3、打开自己的文件输入 import javax.transaction.UserTransaction;结果第三步出错,“can not be resolved”,偶晕之 建议你看看hibernate的事务处理机制http://dev.csdn.net/article/56/56778.shtm还有,不是推荐你用apache的commons-dbutils了吗,参考一下它的实现也可以啊,或者直接引用这个包就可以了,把相关部分交给它去做就可以了,你不需要考虑具体的技术实际细节。你既然采用JTA来进行事务处理,那么jta.jar这个包你引用了么? 搞定了,也看了hibernate中的事务处理(幸好找一位仁兄flysnow的例子,看的非常明白,在此特意感谢),如果以后做的话看来真要用hibernate了,毕竟接触的项目在数据库关系上还是比较复杂地。这次偶偷懒了,把工程中和服务器的SDK换成了J2EE的SDK就全搞定了也不用下什么JTA包了,爽呀。 大家如何理解的面向对象 多线程问题 java能够获得硬盘序列号吗 Java如何实现3D图形信息存储 jfreechart柱行图 怎么最多只能画5个柱子,怎么才能画任意多个。 线程同步的问题。。 帮我写个小程序把 处理这样的异常该怎么做?谢谢 Java下能够实现CAN通信吗?性能怎么样? 求帮助 就40分了,请问高手们从mysql数据库中提取的数据怎么是问号?谢谢 tomcat和jdk不兼容? 很快结贴
1、方法a和方法b
2、方法a要调用方法b现在方法b也可以直接取取链接池里的资源也可以用方法a中已经取出的链接
像这种情况对于方法b来说直接用方法a的接力链接应该要好一点,
但是如果把所有的类似于b的方法都用他的上一组传入的链接不知道合不合理?
我看大多数都是在b里面直接再取一个链接
像这种情况的话如果在a里面有多步操作需要回滚时b里因为有新的链接所以会造成阻塞
也就是说既不要在b中取出新的联接,更不要将a中的联接传给b正确的方法,应该是在程序中有专门DBAdapter来操作数据库。而不论a还是b都调用它来直接获得所需要的数据
在我和程序中也有专门处理数据库操作的包,不知道是不是你指的DBAdapter,我是把insert update query 等方法都封装起来,需要操作数据库的时候就从连接池里取一个联接然后执行所需的方法,这样也就出现了一种情况:
1、比如一个有五步数据操作的过程,其实中每一步都有自己单独的方法,在每步中他们都自己调用连接,这样就存在一个问题,如果中间哪一步出现问题是需要回滚的,但这种情况下回滚不太好弄。
2、另外一种方法就是把这五步都写到一个大的函数体内,但会构成一个超大的函数体,再说也不符合面向对象的特性。
3、我想这样处理不知道合不合适,就是把这五个函数都使用外层函数的CONN作为参数传入这五个方法这样我就可以在外层实现五步操作的回滚了。不知道楼主指的DBAdapter该怎么理解,能不能给点思路,或资料?
总之对数据库的操作要集中在一个地方,而不该分布在不同的地方。
嫩说的“统一加事务”很吸引人,我得先查点资料,再来参与讨论,楼上 星哥2 (晕,这年头叫星的人可真多呀:>只能加个2区分了),如果有什么资料可提供参考的话最好能共享一下,分不够可以另开帖加分,其实我觉得传来传去也不太合适。
public int delete(int sID) {
DataBaseConnection dbc = null;
dbc = new DataBaseConnection();
dbc.getConnection();
UserTransaction transaction = sessionContext.getUserTransaction();//获得JTA事务
try {
transaction.begin(); //开始JTA事务
dbc.executeUpdate("delete from bylaw where ID=" + sID);
dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
transaction.commit(); //提交JTA事务
dbc.close();
return 1;
}
catch (Exception exc) {
try {
transaction.rollback();//JTA事务回滚
}
catch (Exception ex) {
//JTA事务回滚出错处理
ex.printStackTrace();
}
exc.printStackTrace();
dbc.close();
return -1;
}
}
这应该就是"星哥1"所说的transaction ,其实也应该是 "星哥2" 所说的"统一加事务"了
现在发现带星的果然不一样 ^_^
详见:http://dev.csdn.net/article/43/43272.shtm
这种方法的确能解决我的问题,小弟谢楼上客位先,再看两天如果楼下没有反对意见就结帖!
//执行事务处理语句
public boolean runTrans(PreparedStatement [] pst){
boolean b=false;
try{
openConnection();
con.setAutoCommit(false);
for(int i=0;i<pst.length;i++){
pst[i].executeUpdate();
}
con.commit();
b=true;
}
catch(Exception e){
try{
con.rollback();
e.printStackTrace();
}
catch(Exception ex){
ex.printStackTrace();
}
}
finally{
try{
for(int i=0;i<pst.length;i++){
pst[i].close();
}
closeConnection();
}
catch(SQLException sqle){
sqle.printStackTrace();
}
}
return b;
}
具体操作如下:
1、从sun下了个包
2、把打了个javax.jar包放到WEB-INF\lib里面,并在工程里引用这个JAR包
3、打开自己的文件输入 import javax.transaction.UserTransaction;
结果第三步出错,“can not be resolved”,偶晕之
http://dev.csdn.net/article/56/56778.shtm还有,不是推荐你用apache的commons-dbutils了吗,参考一下它的实现也可以啊,或者直接引用这个包就可以了,把相关部分交给它去做就可以了,你不需要考虑具体的技术实际细节。你既然采用JTA来进行事务处理,那么jta.jar这个包你引用了么?