2013-06-07 6 views
1

Мне нужно синхронизировать запрос mysql, так что только один пользователь может получить доступ к указанной части в одно и то же время. Я пробовал synchronized(){}, но это не работает. Пользователи могут одновременно обращаться к методу. Это приложение jsp, использующее tomcat6. Мне нужно это, потому что веб-сервер падает, когда слишком много пользователей запускают запрос одновременно.синхронизация нескольких методов доступа

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.. 
} 

Благодарим за любую помощь.

Edit: как я пытался синхронизировать

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 должен храниться на сервере. Но каков правильный способ сделать это?

+1

не могли бы вы показать, как вы пытались синхронизироваться в своем коде? –

+0

Я обновил свой пост .. –

+1

ваш 'lock' является' null'. Хотя я не слишком знаком с синхронизированными блоками, я думаю, что это должен быть экземпляр, а не 'null' –

ответ

0

Там было неправильное утверждение запроса в другой части моего кода. Если этот запрос был выполнен, он сделал что-то вроде SELECT * FROM TABLE, и это сбило мой сервер mysql. Теперь я исправил его и не должен ограничивать доступ к db. Спасибо за помощь ребята!

0

Я не знаю, как вы синхронизировали метод. Но если класс, содержащий этот метод, не будет работать, он не будет работать.

Ну, это либо синглтон, либо объект, который вы используете для блокировки метода, должны быть для этого работать.

Если вы просто синхронизировали метод, несколько экземпляров класса будут препятствовать вашему намерению.

Но мне кажется, что с вашей архитектурой что-то не так. Вы используете какой-то диспетчер соединений?

0

Если вы используете DBCP, тогда просто настройте атрибут maxActive, который является 100 по defulat. Потоки, которые пытаются получить соединение выше предела, будут заблокированы.

+0

Я никогда не слышал о «DBCP», но это выглядит очень легко понять. Возможно, я должен реализовать его в своем коде. –

+0

уверен, начинайте здесь http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html –

1

Ваш код в порядке, если объект lock одинаковый для всех обрабатываемых запросов.

Как вы можете понять это? Если вы создаете новый класс connect для каждого обрабатываемого вами запроса, то каждый экземпляр этого класса имеет разные lock, а синхронизированный блок может выполняться одновременно разными экземплярами.

Если у вас есть только один экземпляр класса connect, у вас есть только один экземпляр lock, и вы уверены, что ни один из двух потоков не может одновременно выполнять синхронизированный блок.

Однако, даже если у вас есть только один экземпляр класса connect, легко разбить синхронизацию, если рефакторинг кода создает несколько экземпляров этого класса. Если вы хотите быть уверены, что этот код блокировки для всех потоков, то вы должны объявить объект блокировки как статические:

static final Object LOCK = new Object(); 

Теперь вы уверены, что есть только один LOCK в JVM.

Вы также должны иметь в виду, что если ваше приложение работает в кластере, то синхронизация java не будет работать, потому что у вас есть несколько JVM, работающих с одним и тем же приложением. Посмотрите на this question для получения дополнительной информации по этому вопросу.

BTW, попробуйте следовать соглашениям об именах классов. Имена классов должны начинаться с капитала, поэтому переименуйте свой класс на Connect.

1

почему вы не просто использовать синглтон и синхронизированы подключения, или синхронизироваться по методам

public class MyConnection { 

    private Connection mConn; 

    public static synchronized Connection getConnection() { 
    if(mConn == null){ 
    mConn = createNewConnection();//your create method 
    } 
    return mConn; 
    } 

} 
Смежные вопросы