论坛首页 Java企业应用论坛

一个常见的JDBC封装导致的问题

浏览 14041 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (11) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-16  
你这个单例写的,有可能产生死锁
0 请登录后投票
   发表时间:2011-05-16  
sswh 写道

代码真够混乱的。

本来不想回了,算了,还是说一下吧。

悲剧了 写道
public class ConnectionUtil {
	private  static Connection   instance=null;
}


这儿:instance是ConnectionUtil 类的静态变量。

悲剧了 写道
	public static void close(Connection con){
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
	}
}


这儿:close()方法中,置空的con=null,是方法参数。ConnectionUtil.instance 并没有受到影响。


正解,Java的参数都是值传递,非引用传递
0 请登录后投票
   发表时间:2011-05-16  
悲剧了 写道
大家看一个数据库封装类
操作一次没问题,操作两次就报错
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.


Debug调试,发现connection不能真正关掉,使用connection完后,调用close()方法,下次getConnection()时候
instance不为null



public class ConnectionUtil {
	private final static String  url="jdbc:mysql://localhost:3306/qq?useUnicode=true&characterEncoding=UTF-8";
	private final static String  username="root";
	private final static String  password="root";
	private  static Connection   instance=null;
	
	private ConnectionUtil(){
		if(instance==null){
			try {
				Class.forName("org.gjt.mm.mysql.Driver");
				instance=DriverManager.getConnection(url, username, password);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
	}
	
	public static Connection getConnection(){
		if(instance==null){
			new ConnectionUtil();
		}
		return instance;
		
	}
	
	
	public static void close(Connection con,PreparedStatement ps,ResultSet rs){
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
		if(ps!=null){
			try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				ps=null;
			}
		}
		if(rs!=null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				rs=null;
			}
		}
		
	}
	
	public static void close(Connection con,PreparedStatement ps){
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
		if(ps!=null){
			try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				ps=null;
			}
		}
		
		
	}
	
	public static void close(Connection con){
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
	}

}

一个connetion.close掉了就不可以用了,你这里if(instance==null),第二次用的时候install不为null,是一个connection对象,但他的状态时closed,所以下面的if语句块,不会执行。今天没认真看代码,罪过,罪过...

结贴了。。。。有其他结贴方式吗?

0 请登录后投票
   发表时间:2011-05-16  
非常常用的功能,建议先找找有没通用的开源实现
http://commons.apache.org/dbutils/
0 请登录后投票
   发表时间:2011-05-17  
悲剧了 写道
gaosheng08 写道
close()中还要加一句instance = null;


调用的时候传进来的就是instance ,这个connection是通过这个类的getConnection()得到的


instance 和 con 是一个对象的两个引用,假设对象为A, B和C为到A的引用,C=null只是切断了C到A的联系,B与A的联系依然存在。
0 请登录后投票
   发表时间:2011-05-17  
ecokozhangtao 写道
你这个单例写的,有可能产生死锁

连同步都没有,还能出来死锁....
0 请登录后投票
   发表时间:2011-05-17   最后修改:2011-05-17
悲剧了 写道
kakaluyi 写道
悲剧了 写道
gaosheng08 写道
close()中还要加一句instance = null;


调用的时候传进来的就是instance ,这个connection是通过这个类的getConnection()得到的

lz你难道不知道java通过close方法传递进去的instance只是个引用吗,真正的instance是不会置为null的??





哥们我明白了

con,intance 两个引用指向同一个栈,con为空但intance不为空,开始是以为传进去的是intance

Connection con=instance
con=null
但intance不为空

哎,悲剧,估计又要挨骂了


+1
new ConnectionUtil 匿名对象
0 请登录后投票
   发表时间:2011-05-17  
没发现搂主 instance=null 的语句
0 请登录后投票
   发表时间:2011-05-17  
这个单列写的。。。。。。。我看着似乎不敢发言了。
0 请登录后投票
   发表时间:2011-05-18   最后修改:2011-05-18
kakaluyi 写道
算了解释一下,发现楼主还是云里雾里
public void static main(String args[])
{
int i=3;
changevalue(i);
System.out.println(i);
//你以为i现在是2吧,错了,i还是3!不好意思楼主,你理解错误了。这个是很容易搞错的概念
}
public void changevalue(int i)
{
i=2;
}


朋友很热心,但是你却没有明白Java的基本数据类型与引用类型的区别。
你这样会对人造成误导的,不是楼主搞错了而是你搞错了。


楼主的代码写得确实很混乱。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics