gpt4 book ai didi

java - Tomcat 服务器中的任务期间 JDBC 连接丢失

转载 作者:行者123 更新时间:2023-11-30 06:11:59 25 4
gpt4 key购买 nike

我的结构:

  • 使用 Keycloak 的身份验证服务器
  • 一台 Tomcat 8 服务器
  • 一个应用程序(称为A),为所有其他 Web 应用程序提供通用服务,位于 tomcat 8 服务器上
  • 其他网络应用
  • MySQL 服务器数据库,具有不同的 w/r 架构。
  • 可读的 SQL Server

我的所有 webApp 都是在 Spring Boot 中使用 Java 8 开发的。

案例:
在指定的应用程序之一(称为B)中,我调用A的API。此 API 打开与 SQL Server 的连接,用于读取条目并将读取条目的值发送到 B

我在本地机器上运行AB来测试它,并且A官方和B本地.

在测试中我没有任何问题,API 工作正常。

但是当我从官方调用这个 API 时,几秒钟后我在日志中出现了一些错误,并且失去了与数据库的所有连接:

Forwarding to error page from request [/mycontroller/request] due to exception 
[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5ec9a879 has been closed already]


java.lang.IllegalStateException: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5ec9a879 has been closed already

或者:

EntityManager is closed

出现此错误后,我只能重新启动 Tomcat 服务器来恢复与数据库的连接。

这是我的代码,称为 API:

 @Override
public void apiCalled() {
try {
for(Entity c : entityRepository.findEntity()) {
String ftt = keycloakRestTemplate.getForEntity(URI.create(mux+"/api/apiCalled?num="+c.getNumber()), String.class).getBody();
if(ftt == null) {
continue;
}
FttDto f = new ObjectMapper().readValue(ftt, FttDto.class);

c.setNumberF(f.getNumberF());
c.setDateF(convertDate(f.getDateF()));
commessaRepository.save(c);
}
} catch (RestClientException | IOException e) {
LOG.error("Api Service Get error: {}", e.getMessage());
}
}

API代码:

@PersistenceContext(unitName="persistenceUnitI24")
private EntityManager emI24;

public FttDto findByNumber(String number) {
Session session = emI24.unwrap(Session.class);
FttI24 fttListI24 = (FttI24) session.createQuery("select f from FttRg r join r.idFttI24 f join r.nota n where n.nota like '%"+number+"%'")
.setCacheMode(CacheMode.IGNORE)
.uniqueResult();

if(fttListI24 == null) {
return null;
}

FttDto ftt = new FttDto();
ftt.setNumberF(fttListI24.getNumberF());
ftt.setDateF(fttListI24.getDateF());
return ftt;
}

有什么想法吗?

编辑

这是我的数据库连接的 server.xml:

        <Resource 
name="jdbc/schemaA"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="javax.sql.DataSource"
initialSize="2"
maxActive="4"
maxIdle="2"
minIdle="1"
username="user"
password="password"
driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://sqlServer_ip/schemaA"
testOnBorrow="true"
testWhileIdle="true"
validationQuery="select 1"
validationInterval="300000"/>

<Resource
name="jdbc/schemaB"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="javax.sql.DataSource"
initialSize="4"
maxActive="8"
maxWait="10000"
maxIdle="8"
minIdle="4"
username="userB"
password="passB"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://mysqlserver_ip/schemaB?zeroDateTimeBehavior=convertToNull"
testOnBorrow="true"
testWhileIdle="true"
validationQuery="select 1"
validationInterval="300000" />

在 spring 中添加数据源配置。

在网络应用程序上B:

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
@Bean(name = "dataSource")
@ConfigurationProperties(prefix="spring.datasource")
@Primary
public DataSource dataSource() throws NamingException {

if(Arrays.asList(environment.getActiveProfiles()).contains("dev")) {
return new BasicDataSource();
}else {
Context ctxConfig = new InitialContext();
return (DataSource) ctxConfig.lookup("java:comp/env/jdbc/schemaB");
}
}

@Bean
@Primary
public JpaTransactionManager transactionManager() throws NamingException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

return transactionManager;
}

@Bean
public JpaVendorAdapter jpaVendorAdapter(){

HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();

jpaVendorAdapter.setDatabase(Database.MYSQL);
jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setShowSql(false);
jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQLInnoDBDialect");

return jpaVendorAdapter;
}

@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan("domain.mydomain");
entityManagerFactoryBean.setPersistenceUnitName("persistenceUnit");

return entityManagerFactoryBean;
}
}

在网络应用程序上A:

 @Configuration
public class DataSourceI24Config {

@Autowired
private Environment environment;

@Bean(name = "dataSourceI24")
@ConfigurationProperties(prefix = "spring.datasource.i24")
public DataSource dataSourceI24() throws NamingException {
Context ctxConfig = new InitialContext();
return (DataSource) ctxConfig.lookup("java:comp/env/jdbc/schemaA");

}

@Bean(name="transactionManagerI24")
public JpaTransactionManager transactionManagerI24() throws NamingException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryI24().getObject());
return transactionManager;
}

@Bean(name="entityManagerI24")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryI24() throws NamingException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

entityManagerFactoryBean.setDataSource(dataSourceI24());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan("appA.i24.domain");
entityManagerFactoryBean.setPersistenceUnitName("persistenceUnitI24");

[...]

return entityManagerFactoryBean;
}
}

最佳答案

我在使用 h2 数据库时遇到了同样的问题。解决方案是在多连接模式下使用db(多个可能的连接,连接池)。

关于java - Tomcat 服务器中的任务期间 JDBC 连接丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50046417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com