我需要同步mysql查询,因此只有一个用户可以同时访问指定的部分。我试过synchronized(){}
,但这不起作用。用户可以同时访问该方法。这是一个使用tomcat6的jsp web应用程序。我需要这个,因为当太多用户同时运行查询时,网络服务器会崩溃。
String sql = "SELECT * FROM products;"
ResultSet rs;
//This block should be synchronized
Statement s = con.createStatement();
rs = s.excecuteQuery(sql);
while (rs.next()) {
// do some stuff..
}
感谢您的帮助。
编辑:我如何尝试同步
public class connect {
public static String URL = "url";
public static String USER = "root";
public static String PASSWORD = "password";
private Object lock = new Object();
public void getData() {
Connection con;
try {
con = DriverManager.getConnection(URL, USER, PASSWORD);
String sql = "SELECT * FROM products;";
ResultSet rs;
//This block should be synchronized
synchronized(lock) {
Statement s = con.createStatement();
rs = s.executeQuery(sql);
while (rs.next()) {
// do some stuff..
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
我认为对象lock
应存储在服务器上。但是这样做的正确方法是什么?
答案 0 :(得分:1)
如果lock
对象对于正在处理的所有请求都相同,则代码正常。
你怎么能搞清楚?如果为正在处理的每个请求创建新的connect
类,则此类的每个实例都具有不同的lock
,并且synchronized块可以由不同的实例同时执行。
如果您只有connect
类的一个实例,那么您只有一个lock
实例,并且您确信没有两个线程可以同时执行同步块。
但是,即使您只有connect
类的一个实例,如果重构代码会创建此类的多个实例,则很容易中断同步。如果要确保此代码锁定所有线程,则必须将lock对象声明为static:
static final Object LOCK = new Object();
现在您确定JVM中只有一个LOCK
。
您还必须记住,如果您的应用程序在群集中运行,那么Java同步将无法工作,因为您有多个运行相同应用程序的JVM。有关该主题的详细信息,请查看this question。
BTW,尝试遵循类命名约定。类名应以大写字母开头,因此将您的类重命名为Connect
。
答案 1 :(得分:1)
为什么不直接使用单例并同步Connection,或者在方法上同步
public class MyConnection {
private Connection mConn;
public static synchronized Connection getConnection() {
if(mConn == null){
mConn = createNewConnection();//your create method
}
return mConn;
}
}
答案 2 :(得分:0)
我不知道你是如何同步这个方法的。但除非包含该方法的类是单例,否则它将不起作用。
无论是单例还是用于锁定方法的对象都必须能够正常工作。
如果您只是简单地同步了该方法,则该类的多个实例将阻碍您的意图。
但在我看来,您的架构有问题。你在使用某种连接管理器吗?
答案 3 :(得分:0)
如果您正在使用DBCP,则只需通过defulat配置maxActive
属性为100。试图使Connection超过限制的线程将被阻止。
答案 4 :(得分:0)
我的代码的另一部分中有一个错误的查询语句。如果执行了这个查询,它会执行类似SELECT * FROM TABLE
的操作,这会导致我的mysql服务器崩溃。现在我修复了它,不必限制db访问。谢谢你的帮助!