powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Полтергейст
16 сообщений из 16, страница 1 из 1
Полтергейст
    #34792202
Vincent FROST
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По другому не назвать. Суть:

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

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

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

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

Фраза "Методы записи и чтения - синхронизированы" пугает окончательно.
...
Рейтинг: 0 / 0
Полтергейст
    #34792247
Vincent FROST
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если бы дело было только в записи. Возвращается заказ целиком, тетке которая его не делала. При этом в таблице присутствуют оба заказа с позициями и шапками которые забивали соответствующие тётки. Авторство тоже соответствует.
...
Рейтинг: 0 / 0
Полтергейст
    #34792253
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Без деталей реализации дальнейшее обсуждение смысла не имеет. Ни тетки, ни записи, ни шапки, ни таблички, не имеют к Java никакого отношения.
...
Рейтинг: 0 / 0
Полтергейст
    #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
Полтергейст
    #34792385
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vincent FROSTМетоды записи и чтения - синхронизированы.
Жжесть.
Vincent FROSTлежит НулПоинтер эксцепшн но строки на которые он указывает а) разные; б) там хтмл.
давай стектрейс + релевантный код. про б) нипонял.
Vincent FROSTПо другому не назвать
Чудес не бывает.
...
Рейтинг: 0 / 0
Полтергейст
    #34792455
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Плохи Ваши дела, товарищь призывник."
Синхронизация отдельных методов никак не гарантирует целостности данных в БД. Изучите что такое транзакции БД и транзакции бизнес логики.
Если проект большой и он весь так написан - мои Вам соболезнования.

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

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

В системах с большой многопоточной нагрузкой даже бывалые девелоперы натыкаются на мистику которой вашим теткам и не снилось. Что уж говорить о проектах с приведенным выше кодом. Там мистика многопоточности будет частым гостем.
...
Рейтинг: 0 / 0
Полтергейст
    #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
Полтергейст
    #34792527
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vincent FROSTСогласен. Сам до сих пор не верю шо такое может быть ибо своими глазами пока не видел.
Welcome to multithreaded world!
...
Рейтинг: 0 / 0
Полтергейст
    #34792549
Vincent FROST
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz"Плохи Ваши дела, товарищь призывник."
Синхронизация отдельных методов никак не гарантирует целостности данных в БД. Изучите что такое транзакции БД и транзакции бизнес логики.
Если проект большой и он весь так написан - мои Вам соболезнования.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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



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


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