public class ConnDB {
private static Connection conn = null;
public static Connection getConn(){
try{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
conn = DriverManager.getConnectio("jdbc:microsoft:sqlserver://localhost:1433;User=jiayi;password=jiayi456;DatabaseName=jiayi");
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
以上是一个用来获得数据库连接的工具类,下面是一个servletclass a extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
ConnDB con=ConnDB.getConn();
..........
利用con做一些处理
...........con.close();
}
}
因为jsp是多线程的,tomcat对每一个请求都会开辟一个线程来处理,所以会同时有多个线程来运行以上那个servlet,会不会出现这种情况:当一个线程获得conn而进行处理的时候,恰好另一个线程把conn给关闭了?
在网上也看了一些资料,对于方法中的局部变量,每个线程都会开辟相应的内存空间来存储,所以以上方法中的conn(局部变量)在被存放在了每个线程的单调内存空间中,所以并不是出现一个线程正在用conn,而另一个把conn给关了,我是这样理解的,不知道对不对。突然又有了点遗憾,connDB中的Connection可是个全局变量啊?这里会不是照成数据的不同步???
做jsp差不多一年了,以前重没注意过数据的同步安全,现在非常后怕!!!
期待高手给讲讲。
private static Connection conn = null;
public static Connection getConn(){
try{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
conn = DriverManager.getConnectio("jdbc:microsoft:sqlserver://localhost:1433;User=jiayi;password=jiayi456;DatabaseName=jiayi");
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
以上是一个用来获得数据库连接的工具类,下面是一个servletclass a extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
ConnDB con=ConnDB.getConn();
..........
利用con做一些处理
...........con.close();
}
}
因为jsp是多线程的,tomcat对每一个请求都会开辟一个线程来处理,所以会同时有多个线程来运行以上那个servlet,会不会出现这种情况:当一个线程获得conn而进行处理的时候,恰好另一个线程把conn给关闭了?
在网上也看了一些资料,对于方法中的局部变量,每个线程都会开辟相应的内存空间来存储,所以以上方法中的conn(局部变量)在被存放在了每个线程的单调内存空间中,所以并不是出现一个线程正在用conn,而另一个把conn给关了,我是这样理解的,不知道对不对。突然又有了点遗憾,connDB中的Connection可是个全局变量啊?这里会不是照成数据的不同步???
做jsp差不多一年了,以前重没注意过数据的同步安全,现在非常后怕!!!
期待高手给讲讲。
解决方案 »
- 如何添加ip,子网合并问题。
- 求助!spring代理 webservice客户端的问题,困扰我好几天了
- 配置好struts2 为什么提交URL 显示已经到了login.action 却显示404错误?
- 请问怎样把数据库数据导出到EXCEL?(JAVA)
- jsp点击删除后防止二次点击
- 请做过这Struts+Spring+Hibernate视频练习例子的大侠进来看看,谢谢!
- 新建立的java 群希望大家参加 13003822
- 能用web service 处理cookie吗?
- 一个TOMCAT5下的联接的问题,请兄弟们指教!
- 多机集群环境下启动线程,线程执行会跳到集群中的其他节点
- EXTJs和struts2检验框架的问题
- ajax dwr
相当于只有一个实例,但实际上却又需要多个实例,确实是非常不安全。去掉static,用正常的实例化类的方式,这样就安全了
如果不用dao框架,都要自己写个简单的dao工厂的。
另一个线程调用getConn()方法则会将conn重新实例化一遍.
可以将你的数据库工具类设计成一个单例模式,getConn()设计成一个非静态方法,将conn设计成这个方法内的局部变量....
不过最好使用连接池.
如果你要测试servlet是不是多线程的,可以做一个计数器,然后2个页面访问,看看计数器有没有改变,我记得servlet不是线程安全的。
所以你可以使用c3p0或者jndi的连接池来做,不会出这么多问题。
去掉static,用正常的实例化类的方式,这样应该安全了
import java.sql.Connection;
import java.sql.DriverManager;public class ConnDB { static {
try {
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} public static Connection getConn() {
Connection conn = null;
try {
conn = DriverManager
.getConnection("jdbc:microsoft:sqlserver://localhost:1433;User=jiayi;password=jiayi456;DatabaseName=jiayi");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
以上是线程安全的代码..还有几个地方我需要和您解释下1:Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");加载数据库驱动..在整个应用中.只需要加载一次就可以了..
而不是说每次得到一个连接都加载一次驱动..所以,我这里在静态代码块(关于这个名词的解释以及静态代码块的作用,您可以通过百度或google搜一下,我这里就不解释了)中加载一次.而通常我在开发项目的做法是.. 有一个伴随tomcat启动而初始化的Servlet, 再他的init方法中加载数据库驱动..这是第一.2:关于您说的线程安全问题.. 您写的代码的确是有线程安全的隐患.. 原因就是在于.. 这个Connection对象是成员变量.. 去除了static会报语法错误.. 因为静态方法.. 不能直接访问类属性.. 依然能在一个方法中获得这个Connection.. 为什么要使用成员变量呢..??这是我的想法..如果哪里说错了. 请各位大侠指出.. 一起交流交流思想..