gpt4 book ai didi

java - 长时间 session 中连接重置

转载 作者:行者123 更新时间:2023-12-01 13:53:28 25 4
gpt4 key购买 nike

我有一个独立的 Thread 应用程序。这是一个等待消息的监听器,当消息到达时执行一些操作,其中我必须将消息保存在数据库中。但我遇到了问题,因为如果我运行应用程序并“手动发送消息”,一切都会正常工作,但是如果我运行应用程序并在应用程序运行时等待系统的消息(例如,消息到达后一小时)保存到它下沉的数据库,告诉:

java.sql.SQLException:Io 异常:连接重置或者java.sql.BatchUpdateException:Io 异常:连接重置

我正在使用 Hibernate 3.2.6 和 C3p0 0.9.2.1

session 的配置是:

public final class PersistenceUtil{
private static final SessionFactory sessionFactory;

static {
try {
String location = ServiceLocator.getInstance().getConfigurationService().getProperty("adaptor.location");
if (LOC_1.equals(location)) {
sessionFactory = new AnnotationConfiguration().configure("hibernate.1.cfg.xml").buildSessionFactory();
} else if(LOC_2.equals(location)) {
sessionFactory = new AnnotationConfiguration().configure("hibernate.2.cfg.xml").buildSessionFactory();
}else {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}
sessionFactory.openSession();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}


private PersistenceUtil() {
}

public static void shutdown() {
try {
sessionFactory.close();
} catch (HibernateException e) {
LOG.error("PersistanceUtil.shutdown Error: " + e.getMessage());
}

}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}

当我想保存时我会这样做(错误在哪里):

public T save(T entity) {

if (!getSession().getTransaction().isActive()) {
log.warn("Session not active. Starting the session");
getSession().beginTransaction();
}

getSession().save(entity);
getSession().getTransaction().commit();
return entity;
}

我的 hibernate.cfg.xml 是:

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">URL</property>
<property name="connection.username">USER</property>
<property name="connection.password">Password</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- <property name="hibernate.hbm2ddl.auto">update</property> -->
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.timeout">3000</property>
<property name="hibernate.c3p0.max_statements">0</property>
<property name="hibernate.c3p0.idle_test_period">0</property>

<mapping class="MessageEO" />
<mapping class="CustomerEO" />

</session-factory>
</hibernate-configuration>

我做错了什么?提前致谢

最佳答案

为什么在尝试保存数据之前不创建新 session ?根据 Hibernate 的文档,这是原子操作的正确方法。正如我在代码中看到您的评论,您认为开始事务意味着开始新 session 或打开新连接,但这是不正确的。每个 session 可以有多个(但并不总是嵌套的)事务。我总是使用以下模板进行原子操作 - 它永远不会让我失望。我什至在 Eclipse 中将这段代码作为模板:

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// save/ update / delete your entities here
tx.commit();
} catch (RuntimeException ex) {
if (tx != null) {
tx.rollback();
}
throw ex;
} finally {
session.close();
}

原则:

  1. 持有单个SessionFactory对象。创建它的成本很高。
  2. 对于每次批量操作(保存、修改等)或单个实体使用工厂打开新 session - 它是轻量级且线程安全的。
  3. session 本身不是线程安全的。
  4. 始终启动新事务并根据需要滚动提交/回滚它们。即使对于只读数据获取也是如此。
  5. 完成批量操作(释放连接等)后务必关闭 session
  6. 切勿在发生异常的情况下使用相同的 session 。

关于java - 长时间 session 中连接重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19784315/

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