2010-04-11 4 views
1

Я пытаюсь создать тупик базы данных, и я использую JUnit. У меня есть два одновременных теста, которые одновременно обновляют одну и ту же строку в таблице в цикле.Как создать блокировку базы данных с помощью jdbc и JUNIT

Моя идея заключается в том, что вы обновляете строку А в таблице А, а затем строку В в таблице В снова и снова в одном тесте. Затем в то же время вы обновляете таблицу B таблицы B, а затем снова и снова добавляете таблицу A A. По моему мнению, это должно в конечном итоге привести к тупиковой ситуации.

Вот код Для первого теста.

public static void testEditCC() 
{ 
    try{ 
     int rows = 0; 
     int counter = 0; 
     int large=10000000; 
     Connection c=DataBase.getConnection(); 
     while(counter<large) 
     { 
      int pid = 87855; 
      int cCode = 655; 
      String newCountry="Egypt";    
      int bpl = 0; 
      stmt = c.createStatement(); 

      rows = stmt.executeUpdate("UPDATE main " +    //create lock on main table 
                "SET BPL="+cCode+ 
                "WHERE ID="+pid); 
      rows = stmt.executeUpdate("UPDATE BPL SET DESCRIPTION='SomeWhere' WHERE ID=602"); //create lock on bpl table 
      counter++; 
     } 

     assertTrue(rows == 1); 
     //rows = stmt.executeUpdate("Insert into BPL (ID, DESCRIPTION) VALUES ("+cCode+", '"+newCountry+"')"); 

    } 
    catch(SQLException ex) 
    { 
     ex.printStackTrace(); 
     //ex.getMessage(); 
    } 
} 

И вот код для второго теста.

public static void testEditCC() 
{ 
    try{ 
     int rows = 0; 
     int counter = 0; 
     int large=10000000; 
     Connection c=DataBase.getConnection(); 
     while(counter<large) 
     { 
      int pid = 87855; 
      int cCode = 655; 
      String newCountry="Jordan";   
      int bpl = 0; 
      stmt = c.createStatement(); 
      //stmt.close(); 
      rows = stmt.executeUpdate("UPDATE BPL SET DESCRIPTION='SomeWhere' WHERE ID=602"); //create lock on bpl table 
      rows = stmt.executeUpdate("UPDATE main " +   //create lock on main table 
                "SET BPL="+cCode+ 
                "WHERE ID="+pid); 
      counter++; 
     } 

     assertTrue(rows == 1); 
     //rows = stmt.executeUpdate("Insert into BPL (ID, DESCRIPTION) VALUES ("+cCode+", '"+newCountry+"')"); 

    } 
    catch(SQLException ex) 
    { 
     ex.printStackTrace(); 
    } 
} 

Я бегу эти два отдельных тестов JUnit в то же время и я соединяюсь к базе данных Apache Derby, что я работает в сетевом режиме в Eclipse. Может ли кто-нибудь помочь мне понять, почему тупик не происходит? Возможно, я использую JUnit неправильно.

+0

Как вы одновременно используете два метода тестирования? JUnit последовательно выполняет тестовые методы. –

+0

У меня есть два тестовых примера JUnit и запустите их, затем переключитесь на другой и запустите его, и он показывает, как они работают. – Isawpalmetto

+0

Я вижу. Какой уровень изоляции транзакций вы используете? –

ответ

1

Вы должны проверить уровень изоляции транзакции, поскольку он определяет, блокирует ли БД строки, затронутые транзакцией. Если уровень изоляции слишком низок, блокировки не происходит, поэтому нет взаимоблокировки.

Обновление: согласно this page, уровень изоляции tx по умолчанию для Derby считается прочитанным, что должно быть в порядке. На странице стоит прочитать btw, так как это объясняет изоляцию tx и ее различные уровни, и какие проблемы он решает.

Следующий вопрос: а что такое DataBase в вашем коде? Это похоже на нестандартный способ подключения.

Update2: Я думаю, что получил. Цитата the API doc:

Примечание: По умолчанию объект Connection находится в режиме, что означает, что он автоматически совершает изменения после выполнения каждого оператора автоматической фиксации. Если режим автоматической фиксации отключен, метод commit должен быть вызван явно для фиксации изменений; в противном случае изменения базы данных не будут сохранены.

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

Connection c=DataBase.getConnection(); 
c.setAutoCommit(false); 
+0

Итак, это должны быть транзакции, которые я делаю, это не тот тип, который вызывает взаимоблокировки. Я не уверен, что еще попробовать, поэтому мне нужно будет немного почитать. – Isawpalmetto

+0

У меня есть класс, который я назвал «DataBase», в котором есть все мои методы. Один из них - getConnection. Он просто использует метод DriverManager.getConnection (url) из JDBC. – Isawpalmetto

+0

@Isawpalmetto ОК, я думаю, что понял - посмотрю мое последнее обновление. –

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

  • Нет связанных вопросов^_^