2015-08-01 4 views
0

Я использую JNDI ressource в Tomcat8 для подключения к базе данных MS-SQL (Azure). Случайно я испытываю исключение Connection closed, в конечном итоге претерпела Connection peer reset событий. Когда это произойдет, служба мертва (работает в Connection closed для каждого запроса), и перезапуск tomcat (redploying) - это единственный шанс получить его снова.Шаблон для источника данных JDNI

На моем пути, пытаясь решить эту проблему, я дважды (тройной) проверил каждый метод для незакрытых соединений. Уверяю, что каждое соединение открывается как try-with-ressource.

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

  1. Где должен DataSource выделяться по телефону ctx.lookup()? На уровне метода или классе? Например. при использовании аннотации hk2 @Service кажется, что служба создается только один раз, а не по запросу. В настоящее время ctx.lookup() вызывается один раз (в конструкторе), а DataSource хранится в поле класса, а позже - с помощью методов с использованием this.dataSource. Имеет ли это смысл ? Или следует получить DataSource по каждому запросу (= вызов метода)

  2. Как проверить выполнение нескольких параметров источника данных, например. testOnBorrow и removeAbandoned (см. Полную конфигурацию ниже) выполнены правильно? Есть опция logAbandoned, но я ничего не вижу в своих журналах. Где это должно появиться? Могу ли я каким-то образом определить определенный уровень журнала для пула? Я нашел только org.apache.tomcat.jdbc.pool, но этот класс, кажется, только вызывается при создании пула (по крайней мере, это единственный момент, когда появляются журналы, даже на уровне FINEST).

  3. Есть ли общие шаблоны, о которых я не знаю?

Вот моя текущая конфигурация:

<Resource name="jdbc/mssql" 
      auth="Container" 
      type="javax.sql.XADataSource" 
      driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" 
      username="***" 
      password="***" 
      url="jdbc:sqlserver://***.database.windows.net:1433;database=***;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;" 
      factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
      removeAbandonedOnBorrow="true" 
      removeAbandonedTimeout="55" 
      removeAbandonedOnMaintenance="true" 
      timeBetweenEvictionRunsMillis="34000" 
      minEvictableIdleTimeMillis="55000" 
      logAbandoned="true" 
      validationQuery="SELECT 1" 
      validationInterval="34000" 
     /> 

Thx, gapvision

ответ

1

Gapvision, вы можете проверить эту ссылку - What is the good design pattern for connection pooling?

Вероятно, вы хотели бы пойти с шаблоном объекта пула. Надеюсь, что это поможет!

+0

Это не ответ, добавьте его в качестве комментария! –

+0

Я ищу шаблон дизайна! – gapvision

+0

Обновлен мой ответ. Пожалуйста, проверьте. –

0

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

Попробуйте данные весны. Это очень полезно при организации ресурсов для доступа к данным.

Без пружины, без встроенных функций tomcat, вам действительно нужно создать свои собственные синглеты для выделения DataSource или ConnectionPool.

Без пружины (если вы построить веб-приложение для кота), вы можете добавить в web.xml:

<resource-ref> 
<description>H2DB</description> 
<res-ref-name>jdbc/project1</res-ref-name> 
<res-type>javax.sql.DataSource</res-type> 
<res-auth>Container</res-auth> 
</resource-ref> 

И в контексте.XML из кота:

<Resource name="jdbc/project1" auth="Container" type="javax.sql.DataSource" driverClassName="org.h2.Driver" url="jdbc:h2:tcp://localhost/~/project1" username="sa" password="" maxActive="20" maxIdle="10" maxWait="-1"/> 

И тогда вы можете поиск источника данных в каждом запросе:

Context ctx = new InitialContext(); 
Context envContext = (Context) ctx.lookup("java:comp/env"); 
DataSource ds = (DataSource) envContext.lookup("jdbc/project1"); 
Connection conn = null; 
try { 
conn = ds.getConnection(); 
PreparedStatement ps = conn.prepareStatement("INSERT INTO USERS (NAME) VALUES (?)"); 
ps.setString(1,name); 
ps.executeUpdate(); 
response.getWriter().write("added user "+name); 
response.getWriter().write("\n"); 
} finally { 
if (conn!=null) { conn.close(); } 
} 

Или вы можете создать одноплодный класс и поиск DataSource один раз, при запуске или ленив, как и одиночки.

Но лучше попробуйте данные весны.

+0

Хм, похоже, не является ответом на мои вопросы, поскольку он показывает, как включить ресурс JNDI, но не лучший из них – gapvision

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