Небольшой вопрос по бд
От: Аноним  
Дата: 12.03.07 15:23
Оценка:
есть код
...
try
{
OracleConnectionCacheImpl ods = new OracleConnectionCacheImpl();
ods.setURL("jdbc:oracle:thin:@//192.168.64.30:1521/DB2");
ods.setUser("name");
ods.setPassword("pass");

Connection conn1;
conn1 = ods.getConnection();

for (int i=0; i<5; i++)
{
new Thread(new Runnable()
{
public void run()
{
try
{
Statement stmt1 = conn1.createStatement();
ResultSet rs = stmt1.executeQuery("SELECT * FROM TEST");
while (rs.next())
{
obj1 = rs.getObject(1);
obj2 = rs.getObject(2);
obj3 = rs.getObject(3);
System.out.println("row1 = " + obj1.toString() + ", row2 = " + obj2.toString() + ", row3 = " + obj3.toString());
}
}
catch(SQLException ex) {System.out.println(ex.toString()); }
}
}
).start();
}
conn1.close();
ods.close();
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}

Main.java:208: local variable conn1 is accessed from within inner class; needs to be declared final — пишет такую ошибку
когда к Connect добавляю final все равно не пашет
надо чтоб коннект создавался вне потока а sql запрос уже в нем????????????
помогите что надо откорректировать&&&&&&&&&&7
Re: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 12.03.07 15:30
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Main.java:208: local variable conn1 is accessed from within inner class; needs to be declared final — пишет такую ошибку


Тут-то все понятно.

final Connection conn1;
conn1 = ods.getConnection();


А>когда к Connect добавляю final все равно не пашет

И что пишет?

А>надо чтоб коннект создавался вне потока а sql запрос уже в нем????????????

А>помогите что надо откорректировать&&&&&&&&&&7
А зачем connect вне потока? Создвай в нем же. Один connection на несколько конкруентных потоков скорее всего работать не будет.
Re[2]: Небольшой вопрос по бд
От: Аноним  
Дата: 12.03.07 15:33
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>Main.java:208: local variable conn1 is accessed from within inner class; needs to be declared final — пишет такую ошибку


B>Тут-то все понятно.


B>

B>final Connection conn1;
B>conn1 = ods.getConnection();


А>>когда к Connect добавляю final все равно не пашет

B>И что пишет?

А>>надо чтоб коннект создавался вне потока а sql запрос уже в нем????????????

А>>помогите что надо откорректировать&&&&&&&&&&7
B>А зачем connect вне потока? Создвай в нем же. Один connection на несколько конкруентных потоков скорее всего работать не будет.


java.sql.SQLException: Локальный указатель более не действителен
Re[3]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 12.03.07 15:54
Оценка:
Здравствуйте, Аноним, Вы писали:

B>>И что пишет?


B>>А зачем connect вне потока? Создвай в нем же. Один connection на несколько конкруентных потоков скорее всего работать не будет.


А>java.sql.SQLException: Локальный указатель более не действителен

Это ответ на оба вопроса?
Re[4]: Небольшой вопрос по бд
От: Аноним  
Дата: 12.03.07 15:58
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


B>>>И что пишет?


B>>>А зачем connect вне потока? Создвай в нем же. Один connection на несколько конкруентных потоков скорее всего работать не будет.


А>>java.sql.SQLException: Локальный указатель более не действителен

B>Это ответ на оба вопроса?

да, мне надо именно такая архитектура там потом больше коннектов будет
мне надо чтоб установка коннекта была отдельно, а sql запросы в потоке!
Re[5]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 12.03.07 16:09
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>да, мне надо именно такая архитектура там потом больше коннектов будет

А>мне надо чтоб установка коннекта была отдельно, а sql запросы в потоке!

Под установокй подразумеваются наверное параметры? Что тогда мешает поместить это код:

Connection conn1;
conn1 = ods.getConnection();


в код новых потоков?


Обычно при подобном подходе используется connection pool, часто реализованый в виде javax.sql.DataSource
Re[6]: Небольшой вопрос по бд
От: Аноним  
Дата: 12.03.07 16:48
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>да, мне надо именно такая архитектура там потом больше коннектов будет

А>>мне надо чтоб установка коннекта была отдельно, а sql запросы в потоке!

B>Под установокй подразумеваются наверное параметры? Что тогда мешает поместить это код:


B>
B>Connection conn1;
B>conn1 = ods.getConnection();
B>


B>в код новых потоков?



B>Обычно при подобном подходе используется connection pool, часто реализованый в виде javax.sql.DataSource


дело в том что мне надо будет выполнять много sql запросов
и постоянно создавать коннекты не катит! мне надо создать их только один раз
идея та что в потоке кроме sql запросов ничего не должно быть

и еще вопрос тут обязательно в данном случае использовать connection pool? или
можно как то по другому реализовать?
Re[3]: Небольшой вопрос по бд
От: dimok@  
Дата: 13.03.07 05:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>java.sql.SQLException: Локальный указатель более не действителен


Еще бы! Пока стартует поток (а у вас их пять), локальная переменная вполне себе успевает выйти за область видимости. Решение — сделать conn1 полем класса. Это раз.
Второе. Пока потоки старуют вполне себе успевает выполнится conn1.close(), а это уже другая ошибка (вы пока до нее не добрались). Решение — синхронизация.
Третье. 99.9%, что обект соединения не потокобезопасен. И потоки с запросами будут в лучшем случае кидать исключения, в худшем — возвращать лажу. Опять же требуется либо синхронизация, либо свое соединение на каждый поток.

Короче. Пулы вам в помощь.
Re[7]: Небольшой вопрос по бд
От: LDimas Россия  
Дата: 13.03.07 06:13
Оценка: +1
Здравствуйте, Аноним, Вы писали:


А>и еще вопрос тут обязательно в данном случае использовать connection pool? или

А>можно как то по другому реализовать?

Вообще обычно его и используют. А почему ты-то не хочешь?
Re[2]: Небольшой вопрос по бд
От: stenkil  
Дата: 13.03.07 06:56
Оценка:
Здравствуйте, Blazkowicz, Вы писали:


B>Один connection на несколько конкруентных потоков скорее всего работать не будет.


Точно будут грабли. Проверено. Этот вопрос уже обсуждался здесь http://www.rsdn.ru/Forum/Message.aspx?mid=2030611&amp;only=1
Автор: Blazkowicz
Дата: 28.07.06
.
Re[3]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 13.03.07 07:14
Оценка:
Здравствуйте, stenkil, Вы писали:

B>>Один connection на несколько конкруентных потоков скорее всего работать не будет.


S>Точно будут грабли. Проверено. Этот вопрос уже обсуждался здесь http://www.rsdn.ru/Forum/Message.aspx?mid=2030611&amp;only=1
Автор: Blazkowicz
Дата: 28.07.06
.


Это не совсем то. Хотя и сродни.
Re[4]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 13.03.07 07:18
Оценка:
Здравствуйте, dimok@, Вы писали:

D>Еще бы! Пока стартует поток (а у вас их пять), локальная переменная вполне себе успевает выйти за область видимости. Решение — сделать conn1 полем класса. Это раз.


Что за чушь? Не пробовал разобратся каким мифическим образом final локальные переменыне попадают в анонимные классы?


D>Второе. Пока потоки старуют вполне себе успевает выполнится conn1.close(), а это уже другая ошибка (вы пока до нее не добрались). Решение — синхронизация.

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

D>Третье. 99.9%, что обект соединения не потокобезопасен. И потоки с запросами будут в лучшем случае кидать исключения, в худшем — возвращать лажу. Опять же требуется либо синхронизация, либо свое соединение на каждый поток.

Про синхронихацию смотри предыдущее мое замечание.
Re[7]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 13.03.07 07:20
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>дело в том что мне надо будет выполнять много sql запросов

А>и постоянно создавать коннекты не катит! мне надо создать их только один раз
А>идея та что в потоке кроме sql запросов ничего не должно быть
У меня идея в том что хорошо бы для начала разобратся с JDBC и понять что при каждой операции происходит на физическом уровне работы с базой. Тогда все станет на свои места и ряд вопросов отпадет. Хотя это наверное не так-то и просто.

А>и еще вопрос тут обязательно в данном случае использовать connection pool? или

А>можно как то по другому реализовать?
Да, можно реализовать так что на каждый поток будет свое соединение. Но connection pool поможет оптимизировать количество физических соединений к базе.
Re[5]: Небольшой вопрос по бд
От: dimok@  
Дата: 13.03.07 07:23
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Что за чушь? Не пробовал разобратся каким мифическим образом final локальные переменыне попадают в анонимные классы?

Согласен! Погорячился. Однако у товарища — не работает!

D>>Второе. Пока потоки старуют вполне себе успевает выполнится conn1.close(), а это уже другая ошибка (вы пока до нее не добрались). Решение — синхронизация.

B> Такое решение будет равносильно тому что ты эти запросы будешь выполнять в цикле без всяких потоков.
А где я писал, что оно будет правильным? Но работать будет.
Re[8]: Небольшой вопрос по бд
От: Аноним  
Дата: 13.03.07 08:21
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>дело в том что мне надо будет выполнять много sql запросов

А>>и постоянно создавать коннекты не катит! мне надо создать их только один раз
А>>идея та что в потоке кроме sql запросов ничего не должно быть
B>У меня идея в том что хорошо бы для начала разобратся с JDBC и понять что при каждой операции происходит на физическом уровне работы с базой. Тогда все станет на свои места и ряд вопросов отпадет. Хотя это наверное не так-то и просто.

А>>и еще вопрос тут обязательно в данном случае использовать connection pool? или

А>>можно как то по другому реализовать?
B>Да, можно реализовать так что на каждый поток будет свое соединение. Но connection pool поможет оптимизировать количество физических соединений к базе.

Переделал под пул как вы и говорили, но все равно пишет что java.sql.SQLException: Локальный указатель более не действителен


try
        {
        OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource();
        ocpds.setURL("jdbc:oracle:thin:@//192.168.64.30:1521/DB2");
        ocpds.setUser("Login");
        ocpds.setPassword("Pass");
        PooledConnection pc = ocpds.getPooledConnection();
        
        final Connection conn1 = pc.getConnection();
        final Connection conn2 = pc.getConnection();
        final Connection conn3 = pc.getConnection();
        final Connection conn4 = pc.getConnection();
        final Connection conn5 = pc.getConnection();
               
        for (int i=0; i<5; i++)
            {
        new Thread(new Runnable() 
            { 
            public void run() 
                    { 
                        try     
                        {
                    
                        Statement stmt1 = conn1.createStatement();
                        ResultSet rs = stmt1.executeQuery("SELECT * FROM TEST");
                        while (rs.next())
                        {
                        obj1 = rs.getObject(1);
                        obj2 = rs.getObject(2);
                        obj3 = rs.getObject(3);
                        System.out.println("row1 = " + obj1.toString() + ", row2 = " + obj2.toString() + ", row3 = " + obj3.toString());
                        }

                        }
                        catch(SQLException ex) {System.out.println(ex.toString()); }
                    } 
            }
            ).start();
            }

        }
    catch(Exception ex) 
        {
        System.out.println(ex.toString());
        }
Re[9]: Небольшой вопрос по бд
От: an-392  
Дата: 13.03.07 08:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Blazkowicz, Вы писали:


B>>Здравствуйте, Аноним, Вы писали:



А>Переделал под пул как вы и говорили, но все равно пишет что java.sql.SQLException: Локальный указатель более не действителен


Зачем ты взял пять соединений из пула, а используешь только одно и между потоками?
Это не безопасно. Бери соединение на поток и забудь оп роблемах.
Хотя меня терзают смутные сомнения, что тебе действительно нужны потоки.
Колись — что хочешь сделать?
Re[10]: Небольшой вопрос по бд
От: Аноним  
Дата: 13.03.07 08:51
Оценка:
Здравствуйте, an-392, Вы писали:

A3>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Blazkowicz, Вы писали:


B>>>Здравствуйте, Аноним, Вы писали:



А>>Переделал под пул как вы и говорили, но все равно пишет что java.sql.SQLException: Локальный указатель более не действителен


A3>Зачем ты взял пять соединений из пула, а используешь только одно и между потоками?

A3>Это не безопасно. Бери соединение на поток и забудь оп роблемах.
A3>Хотя меня терзают смутные сомнения, что тебе действительно нужны потоки.
A3>Колись — что хочешь сделать?

Мне надо соединение один раз установить, зачем мне 5 раз по циклу устанавливать коннект причем у меня их пять?
я хочу его один раз установить, а в потоке мне надо чтоб выполнялись только sql запросы...
Re[11]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 13.03.07 09:00
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Мне надо соединение один раз установить, зачем мне 5 раз по циклу устанавливать коннект причем у меня их пять?

За тем что 5 парралельных потоков не могут работать с одним соединением одновременно! Сколько тебе это можно повторять.

А>я хочу его один раз установить, а в потоке мне надо чтоб выполнялись только sql запросы...

Нельзя его 1 раз установить. Можно взять соединение из пула в потоке. И в том же потоке положить обратно. А потом когда оно понадбится другому потоку, тот возьем его из пула и после работы положит обратно. Но. Когда тебе вдруг понадобится чтобы все запросы работали одновременно, то тебе для каждого потока свой connection. А со своим "хочу" можешь делать все что угодно. Се ля ва.
Re[12]: Небольшой вопрос по бд
От: Аноним  
Дата: 13.03.07 09:08
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>Мне надо соединение один раз установить, зачем мне 5 раз по циклу устанавливать коннект причем у меня их пять?

B>За тем что 5 парралельных потоков не могут работать с одним соединением одновременно! Сколько тебе это можно повторять.
понял...
А>>я хочу его один раз установить, а в потоке мне надо чтоб выполнялись только sql запросы...
B>Нельзя его 1 раз установить. Можно взять соединение из пула в потоке. И в том же потоке положить обратно. А потом когда оно понадбится другому потоку, тот возьем его из пула и после работы положит обратно. Но. Когда тебе вдруг понадобится чтобы все запросы работали одновременно, то тебе для каждого потока свой connection. А со своим "хочу" можешь делать все что угодно. Се ля ва.
а можно пример как брать это соединение? (с синтаксисиом запутался)
Re[13]: Небольшой вопрос по бд
От: Blazkowicz Россия  
Дата: 13.03.07 09:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Мне надо соединение один раз установить, зачем мне 5 раз по циклу устанавливать коннект причем у меня их пять?

B>>За тем что 5 парралельных потоков не могут работать с одним соединением одновременно! Сколько тебе это можно повторять.
А>понял...
А>>>я хочу его один раз установить, а в потоке мне надо чтоб выполнялись только sql запросы...
B>>Нельзя его 1 раз установить. Можно взять соединение из пула в потоке. И в том же потоке положить обратно. А потом когда оно понадбится другому потоку, тот возьем его из пула и после работы положит обратно. Но. Когда тебе вдруг понадобится чтобы все запросы работали одновременно, то тебе для каждого потока свой connection. А со своим "хочу" можешь делать все что угодно. Се ля ва.
А>а можно пример как брать это соединение? (с синтаксисиом запутался)

Не очень знаком с OracleConnectionPoolDataSource, надо конкретно его доку читать если хочешь правильно его исользовать. Я например не понял что есть PooledConnection.
Но если следовать интерфейсу javax.sql.DataSource.



final Datasource datasource = ...

new Thread(new Runnable() 
{ 
  public void run() 
  { 
     Connection c = null;
    try 
    {  
      c = datasource.getCopnnection();
      //Все что ты хочешь сделать
    }
    catch(SQLException e) 
    {
       //Что-то делаем с ошибками
    }
    finally
    { 
      if(c != null)
      {
           c.close();
      }
    } 
   
  }
}



c.close() надо ещё в один try...catch обернуть. Думаю сам разберешься как.

Теперь попробую объяснить.
c = datasource.getCopnnection() пытается взять соединение из пула. Если есть свободное. Если свободных нет, то проверяет лимит максимального количества соединений. И если лимит не достигнут. То делает новое физическое соединение с базой.
c.close(); не закрывает физически connection а помещает его в пул. И тогда connection будет доступен для переиспользование другим потоком.

Тут какой есть нюанс. База данных ограничивает максимальное клоичество физических подключений. И если ты хочешь чтобы все потоки работали парралельно. То ты, все же, ограничен настройками базы. Если ты хочешь одновременности всегда. То тебе пул не нужен. Тебе нужно одно соединение на каждый поток.
Но пул позволит тебе запустить больше потоков чем может база держать соединений. Но тогда потоки будут работать не совсем парралельно. Параллельно будет работать количество потоков равное лимиту пула. Остальные должны ждать и начать работу как только в пуле появится свободное соединение. Может быть эту логику придется писать самому, зависит от пула.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.