日期:2014-05-20  浏览次数:20593 次

继续问多线程情况下的数据库操作的线程安全性问题
本帖最后由 relike 于 2012-12-01 22:57:42 编辑
刚才那个结了,不过我查了下资料有些新的问题

在做一个程序,executorService动态产生多个Runnable线程
每个线程都有可能执行Sqlserver写入操作,现在sqlserver只有一个连接
也就是多个线程公用一个sqlserver连接

刚查到这个一个资料:

“通过 Microsoft SQL Server 2005 JDBC Driver SQLServerConnection 对象进行的通信是同步的,因此可安全地执行在多个线程中共享一个连接的语句。Statement 和 SQLServerResultSet 类不是线程安全的。所有与 SQL Server Database Engine 的通信都在连接级别同步。在 JDBC 中,事务控制(例如提交和回滚)是在连接级别实现的。因此,如果多线程需要独立的事务控制,则它们必须分别创建和操作自己的连接。”


这个意思是不是Statement并非线程安全,就是说创建Statement对象如果是在线程内创建的话就没什么问题,但是在线程外创建的Statement对象在线程内使用就会出问题?

这个是我SqlServer类里的一个查询方法

  
 public static ResultSet execute(String sql) {
       try {
            Statement sqlStatement=dbConn.createStatement(); //创建Statement对象
            ResultSet rs=sqlStatement.executeQuery(sql); 
            return true;
            }       
       catch (Exception e) {
           e.printStackTrace();
           return null;
       }
         
    }




在线程里我直接这样用


MainClass.SqlServer.execute("insert ......");


这样多个线程同时写数据库的时候会不会有问题?
                    
------解决方案--------------------
了解下你的用户量,数量超大的时候,建议加入一个缓存机制,就是不要频繁访问数据库,先把数据缓存起来,然后一次性写入
------解决方案--------------------
dbConn 如果是定义在类中的一个属性,那么他必然是不安全的。
但是所谓的不安全也只是针对你是对他如何操作,比如你程序对他的操作从来就只有读没有写操作,那么无论你如何多请求过来,在这个程序里面还是正确的,因为他从来就不会对dbConn做写操作。
对于你说的Statement对象,也是一样的道理。
判断他是否安全,看你是如何操作这个对象吧,在线程run方法里面的对象都是在独立的栈里面的,所以说是绝对安全的。但是如何是类中定义的一个对象,那么必然所有的线程都共享这个对象,至于你说的安不安全就针对于你对该对象的读写操作是如何进行的。