Muszę się upewnić, że wielu równoczesnych użytkowników ma dostęp do bazy danych. Chociaż po każdym zatwierdzeniu zamykam sesję, ale czasami mój kod przechodzi do następującego błędu, ale gdy wykonuję tę samą operację kilka razy, to przekracza ona błąd i działa.Jak uniknąć transakcji zagnieżdżonych nieobsługiwanego błędu?
Moja hibernacji jest 4.2.1.Final
Messages:
nested transactions not supported
File: org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
Line number: 152
mój kod
session = HibernateUtil.getSession();
session.getTransaction().begin(); OR session.beginTransaction();
... to do ....
session.getTransaction().commit();
session.close(); OR HibernateUtil.closeSession();
HibernateUtil
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal();
private static SessionFactory sessionFactory;
private static SessionFactory configureSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
} catch (HibernateException e) {
System.out.append("** Exception in SessionFactory **");
e.printStackTrace();
}
return sessionFactory;
}
static {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateUtil() {
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() throws HibernateException {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
}
Konfiguracja
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/MyProject
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">12</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="com.project.common.Project" />
<mapping class="com.project.common.School" />
<mapping class="com.project.common.Address" />
<mapping class="com.project.common.Female" />
<mapping class="com.project.common.Male" />
<mapping class="com.project.common.Credential" />
<mapping class="com.project.common.Users" />
</session-factory>
</hibernate-configuration>
Wygląda na to, że jest to dla mnie zagrożenie rasowe; istnieje wiele pułapek na pisanie własnych transakcji "ThreadLocal". Zdecydowanie odradzam pisanie własnego kodu zarządzania sesją, używaj jednego z ['CurrentSessionContext'] (http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/context/CurrentSessionContext.html) wdrożone wdrożenia. –
czy znasz jakiś przykład? –
Może zacznij od [dokumentacji] (http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/architecture.html#architecture- current_session). –