用static方法封装数据库操作,多用户并发时会不会有问题?

时间:2022-08-29 11:26:56
如果不用static方法每次调用时都要生成个实例 userDao dao = new UserDao(); 然后再 dao.getUser(name); 我想直接把getUser()方法设为static,这样每次调用就可以不必new一个UserDao对象。但这样做多用户并发不知道会不会有问题?

29 个解决方案

#1


??关注,总觉得楼主方法怪怪的

#2


没见过这种用法,请楼主三思

#3


这得看你的getUser()是怎么写的,
如果你的getUser确实是static,那么当然是可行的
这样的话,你的getUser里的和数据连接的要么就是传进来的,要么就是它自己去连数据库的

#4


关注!

静态的方法是不是有点象一个“连接池”,小弟不才,学习中!!!

#5


感觉不行,但是用singleton模式可以

#6


getUser()方法大至是这样的,根据用户名从数据库中取数据并放到 reguserInfo对象中返回,返回数据库连接已关闭。
public static reguserInfo getUser(String name){
    userInfo reguser = new userInfo();
    try
    {
        conn = dbManage.getConnection("mysql");
        ps = conn.prepareStatement("SELECT * FROM reguser WHERE name = ?");
        ps.setString(1, name);
        rs = ps.executeQuery();
        if(rs.next()){
            reguser.setName(rs.getString(2));
        }
    }
    catch (SQLException e) {
      System.out.print(e.getMessage());
    }
    finally {
      try {
        if (rs != null)
          rs.close();
        if (ps != null)
          ps.close();
        if (dbManage != null)
          dbManage.freeConnection("mysql", conn);
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    return reguser;
}


如果这个方法不是static的在使用时要new一个Dao对象,但现在这个方法是static 的,在直接使用时不知会不会有问题?

#7


up 继续关注!

#8


我也是这样干的,没发现有什么问题:)~

#9


可以呀。我用C#写过。不过Java就是这两周工作需要才用的。不过我也写了一个,觉得目前没有发现问题。
其实只要你保证对数据链表的操作是互斥的就可以。也可以将getConnect.

#10


我也在C#中这样写过,没有问题!

楼主可以看看一下MS的SQLHelper

都是static

#11


可不可以这样理解,static方法虽然是静态的,在内存中不管new多少个所在类的实例,但只要这个static方法内部所调用的成员全是private的就不会有事,但如果有public的成员恐怕就会出问题了吧.

#12


理论上有问题,如会出现用户的口令跟自己设定的不一致也可登录的现象,
原因很简单,多用户时总有时候是并行操作的,这时,问题理论上会产生。

#13


可以的,这个类其实不含element,只有function

#14


gz

#15


学习中

#16


不行,你的那个方法有问题.
public static reguserInfo getUser(String name){
    userInfo reguser = new userInfo();
    try
    {
1.       conn = dbManage.getConnection("mysql");
        ......
    }
    catch (SQLException e) {
      System.out.print(e.getMessage());
    }
    finally {
      try {
        ......
        if (dbManage != null)
2.          dbManage.freeConnection("mysql", conn);
      }
        ......
    }
conn是类变量么?如果是类变量,当2个用户同时访问,产生A,B2个线程。A先到了语句1,还没有到语句2的时候,B又到了语句1,那么当A运行到语句2的时候,关闭的连接就是B线程的连接。那么B线程会执行出错,A线程会不能关闭连接。如上ps,rs也有一样的问题。
静态方法中使用静态类变量,一定要注意保持同步,除非静态类变量为只读,否则一个类变量同时只应该有一个线程访问。

#17


语句一应该改为:Connection conn = dbManage.getConnection("mysql");

#18


ps和rs也该new一个,呵呵。不过使用静态方法有很多不便利的地方,一般在工具类里面比较多使用。DAO一般不用静态方法,因为你该有一个抽象DAO接口,或者抽象DAO类,然后让具体的DAO类继承于这个DAO,如:
public class UserDAO extends AbstractDAO
静态方法是不可以用于继承的。

#19


嗯......可以这样用...因为你只是get操作

#20


沧海月明,我为了说明问题忘了把方法开头的几个语句加上了
public static reguserInfo getUser(String name){
    userInfo reguser = new userInfo();
    Connection conn = null;
    PreparedStatement ps = null;
    MySqlDBConnectionManager dbManage = MySqlDBConnectionManager.getInstance();
    try{....
这样的话还会不会有你所说的问题?


#21


其实我想知道的实质是当两个并发用户同时调用一个servlet,并且这个servlet调用了一个static方法,那么这时这个static方法所在的类究竞在内存中是怎样的,比如说第一个用户给static方法传了a这个参数,另一个用户传了b这个参数,那这个a和b在内存中是会是怎样呢?哎!都是并发惹的祸。

#22


没事

#23


队列操作....挨个出栈...并不是真正并发的

#24


放心不会有事的,出了事我负责不过老大还是要补一下并发是怎么产生的再说。

#25


在类中静态方法不会有问题,如果是静态变量问题就大了。。。

所以,用类的变量的时候一定要注意并发性。

#26


呵呵,这样是可以.总之我还是不建议在DAO类中使用静态方法,这样的设计不是DAO模式,不便扩展.

#27


建议楼主把数据和数据库操作分离开,数据对象BEAN来存储记录信息

#28


加同步,没问题

#29


你的初衷是什么?如果是为了节省创建对象时耗费的时间和内存,那么这个方法是不错的。
不过我看这样的做法忽略了一个最应该被节省的东西:建立数据库链接所耗费的时间。
尽管你不是每次都实例化一个对象,但是你每次都新创建了一个新的链接。对于一个数据库操作来说,其实时间大多数都耗费在创建链接上。如果你能把这个问题解决,那么你这种方法就比较完美了。不如用连接池吧。每次取得一个链接比每次创建一个链接要节省很多的时间。
要做就做得彻底。

#1


??关注,总觉得楼主方法怪怪的

#2


没见过这种用法,请楼主三思

#3


这得看你的getUser()是怎么写的,
如果你的getUser确实是static,那么当然是可行的
这样的话,你的getUser里的和数据连接的要么就是传进来的,要么就是它自己去连数据库的

#4


关注!

静态的方法是不是有点象一个“连接池”,小弟不才,学习中!!!

#5


感觉不行,但是用singleton模式可以

#6


getUser()方法大至是这样的,根据用户名从数据库中取数据并放到 reguserInfo对象中返回,返回数据库连接已关闭。
public static reguserInfo getUser(String name){
    userInfo reguser = new userInfo();
    try
    {
        conn = dbManage.getConnection("mysql");
        ps = conn.prepareStatement("SELECT * FROM reguser WHERE name = ?");
        ps.setString(1, name);
        rs = ps.executeQuery();
        if(rs.next()){
            reguser.setName(rs.getString(2));
        }
    }
    catch (SQLException e) {
      System.out.print(e.getMessage());
    }
    finally {
      try {
        if (rs != null)
          rs.close();
        if (ps != null)
          ps.close();
        if (dbManage != null)
          dbManage.freeConnection("mysql", conn);
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    return reguser;
}


如果这个方法不是static的在使用时要new一个Dao对象,但现在这个方法是static 的,在直接使用时不知会不会有问题?

#7


up 继续关注!

#8


我也是这样干的,没发现有什么问题:)~

#9


可以呀。我用C#写过。不过Java就是这两周工作需要才用的。不过我也写了一个,觉得目前没有发现问题。
其实只要你保证对数据链表的操作是互斥的就可以。也可以将getConnect.

#10


我也在C#中这样写过,没有问题!

楼主可以看看一下MS的SQLHelper

都是static

#11


可不可以这样理解,static方法虽然是静态的,在内存中不管new多少个所在类的实例,但只要这个static方法内部所调用的成员全是private的就不会有事,但如果有public的成员恐怕就会出问题了吧.

#12


理论上有问题,如会出现用户的口令跟自己设定的不一致也可登录的现象,
原因很简单,多用户时总有时候是并行操作的,这时,问题理论上会产生。

#13


可以的,这个类其实不含element,只有function

#14


gz

#15


学习中

#16


不行,你的那个方法有问题.
public static reguserInfo getUser(String name){
    userInfo reguser = new userInfo();
    try
    {
1.       conn = dbManage.getConnection("mysql");
        ......
    }
    catch (SQLException e) {
      System.out.print(e.getMessage());
    }
    finally {
      try {
        ......
        if (dbManage != null)
2.          dbManage.freeConnection("mysql", conn);
      }
        ......
    }
conn是类变量么?如果是类变量,当2个用户同时访问,产生A,B2个线程。A先到了语句1,还没有到语句2的时候,B又到了语句1,那么当A运行到语句2的时候,关闭的连接就是B线程的连接。那么B线程会执行出错,A线程会不能关闭连接。如上ps,rs也有一样的问题。
静态方法中使用静态类变量,一定要注意保持同步,除非静态类变量为只读,否则一个类变量同时只应该有一个线程访问。

#17


语句一应该改为:Connection conn = dbManage.getConnection("mysql");

#18


ps和rs也该new一个,呵呵。不过使用静态方法有很多不便利的地方,一般在工具类里面比较多使用。DAO一般不用静态方法,因为你该有一个抽象DAO接口,或者抽象DAO类,然后让具体的DAO类继承于这个DAO,如:
public class UserDAO extends AbstractDAO
静态方法是不可以用于继承的。

#19


嗯......可以这样用...因为你只是get操作

#20


沧海月明,我为了说明问题忘了把方法开头的几个语句加上了
public static reguserInfo getUser(String name){
    userInfo reguser = new userInfo();
    Connection conn = null;
    PreparedStatement ps = null;
    MySqlDBConnectionManager dbManage = MySqlDBConnectionManager.getInstance();
    try{....
这样的话还会不会有你所说的问题?


#21


其实我想知道的实质是当两个并发用户同时调用一个servlet,并且这个servlet调用了一个static方法,那么这时这个static方法所在的类究竞在内存中是怎样的,比如说第一个用户给static方法传了a这个参数,另一个用户传了b这个参数,那这个a和b在内存中是会是怎样呢?哎!都是并发惹的祸。

#22


没事

#23


队列操作....挨个出栈...并不是真正并发的

#24


放心不会有事的,出了事我负责不过老大还是要补一下并发是怎么产生的再说。

#25


在类中静态方法不会有问题,如果是静态变量问题就大了。。。

所以,用类的变量的时候一定要注意并发性。

#26


呵呵,这样是可以.总之我还是不建议在DAO类中使用静态方法,这样的设计不是DAO模式,不便扩展.

#27


建议楼主把数据和数据库操作分离开,数据对象BEAN来存储记录信息

#28


加同步,没问题

#29


你的初衷是什么?如果是为了节省创建对象时耗费的时间和内存,那么这个方法是不错的。
不过我看这样的做法忽略了一个最应该被节省的东西:建立数据库链接所耗费的时间。
尽管你不是每次都实例化一个对象,但是你每次都新创建了一个新的链接。对于一个数据库操作来说,其实时间大多数都耗费在创建链接上。如果你能把这个问题解决,那么你这种方法就比较完美了。不如用连接池吧。每次取得一个链接比每次创建一个链接要节省很多的时间。
要做就做得彻底。