Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Полтергейст / 16 сообщений из 16, страница 1 из 1
11.09.2007, 17:39:26
    #34792202
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
По другому не назвать. Суть:

Есть веб приложение. Сидят две тётки и шпарят заказы - сначала забивается и сохраняется шапка, потом позиции. В какойто момент у одной из теток валится эксцепшн, и если в этот момент вторая тетка добавляла позицию - она видит перед собой документ который сделала первая тётка... Пробовали дебажить - повторить ошибку так и не смогли. В логах лежит НулПоинтер эксцепшн но строки на которые он указывает а) разные; б) там хтмл.

Методы записи и чтения - синхронизированы. Думалось про Юзера, данные которого фигурируют в параметрах метода при сохранении и берутся из сессии, но сессия в порядке.

Мож кто сталкивался с такой бородой?
...
Рейтинг: 0 / 0
11.09.2007, 17:45:20
    #34792230
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Похоже на ошибку уровня доступа к БД. Судя по всему транзакицонность не знакомое проекту понятие. Первая тетка вносит данные, получает ошибку но транзакция не откатывается.
Вторая тетка сохраняет, и вместо получения своей записи из базы получает последнюю внесенную запись.

Вопрос к Java не имеет никакого отношения. Грабли с вероятностью 99.9% в проекте. Без раскрытия кода и описания способа контроля многопоточности вопрос решить не возможно.

Фраза "Методы записи и чтения - синхронизированы" пугает окончательно.
...
Рейтинг: 0 / 0
11.09.2007, 17:49:56
    #34792247
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Если бы дело было только в записи. Возвращается заказ целиком, тетке которая его не делала. При этом в таблице присутствуют оба заказа с позициями и шапками которые забивали соответствующие тётки. Авторство тоже соответствует.
...
Рейтинг: 0 / 0
11.09.2007, 17:51:36
    #34792253
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Без деталей реализации дальнейшее обсуждение смысла не имеет. Ни тетки, ни записи, ни шапки, ни таблички, не имеют к Java никакого отношения.
...
Рейтинг: 0 / 0
11.09.2007, 18:02:22
    #34792299
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Читаем
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
     public   synchronized  OrderHeader getOrderHeader( int  xOID){
        OrderHeader oh =  new  OrderHeader();
        Statement stm =  null ;
        ResultSet rs =  null ;
         try  {
             try  {
                conn =  new  lbConnector().getConn();
            }  catch  (Exception e){
                e.printStackTrace();
            }           
            stm = conn.createStatement();
            String qry = "select * from orders where id="+xOID;
            rs = stm.executeQuery(qry);
            
             if (rs.next()){
                oh.iOrderID = rs.getInt( 1 );
...
            }

        }  catch  (SQLException e){
            e.printStackTrace();
        }  finally  {
             if ( rs !=  null  )
                 try  { rs.close(); }  catch ( SQLException ignore ) {}
             if ( stm !=  null  )
                 try  { stm.close(); }  catch ( SQLException ignore ) {}
             if ( conn !=  null  )
                 try  { conn.close(); }  catch ( SQLException ignore ) {}
        }
        
         return  oh;
    }

Сохраняем
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
    public   synchronized   int  saveOHeader( int  xCst,  int  xSt,  int  xPt,  int  xAgent, String xDDate, String xPDate,  float  xCredit,  float  xDiscount,  int  xUID){
        Statement stm =  null ;
        ResultSet rs =  null ;
         int  x =  0 ;
         try  {
             try  {
                conn =  new  lbConnector().getConn();
            }  catch  (Exception e){
                e.printStackTrace();
            }
            stm = conn.createStatement();
            String qry = "insert into orders set ...";
            stm.executeUpdate(qry);
            rs = stm.getGeneratedKeys();
             if (rs.next()){
                x = rs.getInt( 1 );    
            }
        }  catch  (SQLException e) {
            e.printStackTrace(); 
        }  finally  {
             if ( rs !=  null  )
                 try  { rs.close(); }  catch ( SQLException ignore ) {}
             if ( stm !=  null  )
                 try  { stm.close(); }  catch ( SQLException ignore ) {}
             if ( conn !=  null  )
                 try  { conn.close(); }  catch ( SQLException ignore ) {}
        }                
         return  x;
    }

из сервлета вызывается int x = xx.saveOHeader(...) по условию.

Хз шо еще необходимо?
...
Рейтинг: 0 / 0
11.09.2007, 18:23:22
    #34792385
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Vincent FROSTМетоды записи и чтения - синхронизированы.
Жжесть.
Vincent FROSTлежит НулПоинтер эксцепшн но строки на которые он указывает а) разные; б) там хтмл.
давай стектрейс + релевантный код. про б) нипонял.
Vincent FROSTПо другому не назвать
Чудес не бывает.
...
Рейтинг: 0 / 0
11.09.2007, 18:38:54
    #34792455
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
"Плохи Ваши дела, товарищь призывник."
Синхронизация отдельных методов никак не гарантирует целостности данных в БД. Изучите что такое транзакции БД и транзакции бизнес логики.
Если проект большой и он весь так написан - мои Вам соболезнования.

Первое чем стоит занятся это накатить транзакции на бизнес операции. К примеру, есть одна операция "тетка сохраняет данные", она в коде превращается к пачке обращений к БД
- сохранить шапку
- сохранить записи
- сохранить ещё чего-нить

Так вот все обрщения к БД для одной бизнес-операции очень желательно выполнять в одной изолированой транзакции. Тогда можно как минимум гарантировать что разные тетки работая в разных транзакциях одновременно не насрут друг другу. Это с точки зрения базы. Могу быть и другие критичные ресурсы. В общем надо много и настойчиво изучать многопоточность.

В системах с большой многопоточной нагрузкой даже бывалые девелоперы натыкаются на мистику которой вашим теткам и не снилось. Что уж говорить о проектах с приведенным выше кодом. Там мистика многопоточности будет частым гостем.
...
Рейтинг: 0 / 0
11.09.2007, 18:49:49
    #34792494
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Vincent FROSTлежит НулПоинтер эксцепшн но строки на которые он указывает а) разные; б) там хтмл.
давай стектрейс + релевантный код. про б) нипонял.

Про б). at org.apache.jsp.orders_jsp._jspService(orders_jsp.java:173) тут кроме хтмла нифига нет. Страница собирается из нескольких инклюдов. Вариант тока если собирать страницу без включений и пытаться воспроизвести ошибку, что не есть возможно на данный момент. Если убрать всю разметку то остаётся следующее:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
<%UserData ud = (UserData)session.getAttribute("User");%>
...
<% if (aa.sAction !=  null  && aa.sAction.equals("posAdd")){%>
...
    <%OrderHeader oh = tb.getOrderHeader(aa.iRID);%>
...
}
дальше опять разметка. aa.iRID - это как раз идентификатор шапки.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
 10 . 09 . 2007   10 : 35 : 10  org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service()  for  servlet jsp threw exception
java.lang.NullPointerException
	at org.apache.jsp.orders_jsp._jspService(orders_jsp.java: 173 )
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java: 97 )
	at javax.servlet.http.HttpServlet.service(HttpServlet.java: 802 )
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java: 332 )
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java: 314 )
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java: 264 )
	at javax.servlet.http.HttpServlet.service(HttpServlet.java: 802 )
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java: 252 )
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java: 173 )
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java: 672 )
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java: 463 )
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java: 398 )
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java: 301 )
	at xxx.lb_engine.doPost(lb_engine.java: 878 )
	at javax.servlet.http.HttpServlet.service(HttpServlet.java: 709 )
	at javax.servlet.http.HttpServlet.service(HttpServlet.java: 802 )
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java: 252 )
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java: 173 )
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java: 213 )
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java: 178 )
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java: 126 )
	at org.jstripe.tomcat.probe.Tomcat55AgentValve.invoke(Tomcat55AgentValve.java: 20 )
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java: 105 )
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 107 )
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java: 148 )
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java: 869 )
	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java: 664 )
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java: 527 )
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java: 80 )
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java: 684 )
	at java.lang.Thread.run(Thread.java: 619 )


Vincent FROSTПо другому не назвать
Чудес не бывает.
Согласен. Сам до сих пор не верю шо такое может быть ибо своими глазами пока не видел.
...
Рейтинг: 0 / 0
11.09.2007, 18:57:59
    #34792527
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Vincent FROSTСогласен. Сам до сих пор не верю шо такое может быть ибо своими глазами пока не видел.
Welcome to multithreaded world!
...
Рейтинг: 0 / 0
11.09.2007, 19:02:45
    #34792549
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Blazkowicz"Плохи Ваши дела, товарищь призывник."
Синхронизация отдельных методов никак не гарантирует целостности данных в БД. Изучите что такое транзакции БД и транзакции бизнес логики.
Если проект большой и он весь так написан - мои Вам соболезнования.

Первое чем стоит занятся это накатить транзакции на бизнес операции. К примеру, есть одна операция "тетка сохраняет данные", она в коде превращается к пачке обращений к БД
- сохранить шапку
- сохранить записи
- сохранить ещё чего-нить

Так вот все обрщения к БД для одной бизнес-операции очень желательно выполнять в одной изолированой транзакции. Тогда можно как минимум гарантировать что разные тетки работая в разных транзакциях одновременно не насрут друг другу. Это с точки зрения базы. Могу быть и другие критичные ресурсы. В общем надо много и настойчиво изучать многопоточность.

В системах с большой многопоточной нагрузкой даже бывалые девелоперы натыкаются на мистику которой вашим теткам и не снилось. Что уж говорить о проектах с приведенным выше кодом. Там мистика многопоточности будет частым гостем.

Есть мнение, шо не все были рождены гениями, более того - не все смотрят на одни и теже вещи под одним и тем же ракурсом. До кучи, они еще и информацию воспринимают по разному...

Про многопоточность - согласен. В виду того, шо это по сути первый проект который делается на жабе - всё еще впереди. На данный момент хочется получить рабочий кусок кода который не будет есть моск, после чего сесть и заняться литературоведением и гуглеползанием с целью выяснения почему и как.

В текущей ситуации смущает только то, что а) ошибку не повторить на девелоперской машине; б) неясны условия возникновения ситуации которая приводит к ошибке. Из того, что просится с ходу на ум - теряется сессия в которой лежит идентификатор заказа. А вот на вопрос почему - ответа пока ненашол.
...
Рейтинг: 0 / 0
11.09.2007, 19:03:46
    #34792557
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
BlazkowiczWelcome to multithreaded world!

Ага, спасибо.
...
Рейтинг: 0 / 0
11.09.2007, 19:45:07
    #34792677
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Vincent FROSTЕсть мнение, шо не все были рождены гениями, более того - не все смотрят на одни и теже вещи под одним и тем же ракурсом. До кучи, они еще и информацию воспринимают по разному...

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

Vincent FROSTПро многопоточность - согласен. В виду того, шо это по сути первый проект который делается на жабе - всё еще впереди. На данный момент хочется получить рабочий кусок кода который не будет есть моск, после чего сесть и заняться литературоведением и гуглеползанием с целью выяснения почему и как.

Из показанного рабочий кусок кода получить сложно. Столько всяких советов, хочется надавать. Но не буду. Опять нарвусь на грубость.

Vincent FROSTВ текущей ситуации смущает только то, что а) ошибку не повторить на девелоперской машине;
Ошибки многопоточности вообще повторить не реально почти в 90% случаев. Только дать нужную нагрузку на сервер тестами и смотреть весело на все новые и новые исключения.

Vincent FROST
б) неясны условия возникновения ситуации которая приводит к ошибке. Из того, что просится с ходу на ум - теряется сессия в которой лежит идентификатор заказа. А вот на вопрос почему - ответа пока ненашол.
"Теряется сессия" - очень похоже на желание обвинить кого-нибудь ещё в своих ошибках. Никто ни куда сам по сете не теряется. Проанализируйте откуда берется xOID и каким образом он может принимать не верные значения.
И уберите к черту synchronized, он Ваш код совсем не лечит.
...
Рейтинг: 0 / 0
11.09.2007, 20:02:08
    #34792696
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Blazkowicz Vincent FROSTЕсть мнение, шо не все были рождены гениями, более того - не все смотрят на одни и теже вещи под одним и тем же ракурсом. До кучи, они еще и информацию воспринимают по разному...

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

Vincent FROSTПро многопоточность - согласен. В виду того, шо это по сути первый проект который делается на жабе - всё еще впереди. На данный момент хочется получить рабочий кусок кода который не будет есть моск, после чего сесть и заняться литературоведением и гуглеползанием с целью выяснения почему и как.

Из показанного рабочий кусок кода получить сложно. Столько всяких советов, хочется надавать. Но не буду. Опять нарвусь на грубость.

Vincent FROSTВ текущей ситуации смущает только то, что а) ошибку не повторить на девелоперской машине;
Ошибки многопоточности вообще повторить не реально почти в 90% случаев. Только дать нужную нагрузку на сервер тестами и смотреть весело на все новые и новые исключения.

Vincent FROST
б) неясны условия возникновения ситуации которая приводит к ошибке. Из того, что просится с ходу на ум - теряется сессия в которой лежит идентификатор заказа. А вот на вопрос почему - ответа пока ненашол.
"Теряется сессия" - очень похоже на желание обвинить кого-нибудь ещё в своих ошибках. Никто ни куда сам по сете не теряется. Проанализируйте откуда берется xOID и каким образом он может принимать не верные значения.
И уберите к черту synchronized, он Ваш код совсем не лечит.

Про грубость несовсем понял. Если мой пост можно считать "накатом" - примите мои извинения, ибо не хотел быть грубым, и более того, даже в мыслях небыло, что мои слова можно трактовать именно таким образом.

Про теряется сессиия... отнють, даже не пытался обвинять. Просто указал на одну из причин. xOID берется из реквеста куда попадает с формы и держится пока документ не сохранен. Проверю еще раз логику с учётом замечаний.
...
Рейтинг: 0 / 0
12.09.2007, 12:32:23
    #34793952
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Vincent FROSTПро грубость несовсем понял. Если мой пост можно считать "накатом" - примите мои извинения, ибо не хотел быть грубым, и более того, даже в мыслях небыло, что мои слова можно трактовать именно таким образом.
Да, не про тебя конкретно. Просто вот такое частый случай, когда пытаешься слишком много наводок дать.
Поэтому даже не заикаюсь про потенциальный SQL Injection и PreparedStatement.


Vincent FROSTПро теряется сессиия... отнють, даже не пытался обвинять. Просто указал на одну из причин. xOID берется из реквеста куда попадает с формы и держится пока документ не сохранен. Проверю еще раз логику с учётом замечаний.
Если используется контейнер сервлетов не 10ти летней давности, то сессия никуда не теряется. Максимум она может заэкспарится по таймауту. Но тогда все равно не ясно откуда берется id другой записи другого пользхователя. Вообще список можно придумать довольно длинный, попробую на вскидку
- все таки операции с БД где-то не верно работают. Мне это кажется наиболее вероятным.
- поля в классах-сервлетах
- любые статические поля в приложения
- ThreadLocal, если из него забывают удалять значение, потому как зачастую поток берется из пула. Хотя в этом варианте я очень сомневаюсь, судя по коду.
- различного вида кэши, но это тоже маловероятно.
...
Рейтинг: 0 / 0
13.09.2007, 14:19:31
    #34797738
mors78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
Vincent FROST...На данный момент хочется получить рабочий кусок кода который не будет есть моск, после чего сесть и заняться литературоведением и гуглеползанием с целью выяснения почему и как Лучше вначале подумать(изучить вопрос, почитать литературу), а потом сделать правильно, а если нужны работающие примеры для понимания принципов,то лучше брать их из литературы, а то потом можно дого полтергейстов искать.



ЗЫ Если долго работать программистом начинаешь понимать, что чудес и полтергейста нет, а есть суеверия, незнания и ситуация, когда сам где-то, что-то не додумал. Или(как правило намного реже для начинающих программистов) когда кто-то написал кривизну, которую ты пытаешься использовать в своем коде :).
...
Рейтинг: 0 / 0
19.09.2007, 23:46:01
    #34812901
Vincent FROST
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Полтергейст
2Blazkowicz: спасибо, работает ;)
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Полтергейст / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]