即使我已经手动启动了事务,我仍然会得到这个错误。
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
transaction = session.getTransaction();
if(!transaction.isActive())
{
transaction = session.beginTransaction();
}
accessToken = session.get(OAuthAccessToken.class, token);hibernate.cfg.xml
<property name="hibernate.connection.autoReconnect">true</property>
<!-- Use the C3P0 connection pool. -->
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<!-- Disable second-level cache. -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_minimal_puts">false</property>
<property name="max_fetch_depth">3</property>
<!-- Bind the getCurrentSession() method to the thread. -->
<property name="current_session_context_class">thread</property>
<property name="hibernate.jdbc.batch_size">30</property>HibernateUtils
public class HibernateUtil
{
private static final SessionFactory sessionFactory;
static
{
try
{
// Create the SessionFactory from hibernate.cfg.xml
Configuration config = new Configuration().configure();
config.setProperty("hibernate.show_sql", String.valueOf(ConfigManager.getInstance().getBoolean(Consts.CONFIG_DB_SHOW_SQL, false)));
config.setProperty("hibernate.format_sql", String.valueOf(ConfigManager.getInstance().getBoolean(Consts.CONFIG_DB_FORMAT_SQL, false)));
config.setProperty("hibernate.dialect", ConfigManager.getInstance().getString(Consts.CONFIG_DB_DIALECT, "org.hibernate.dialect.MySQLDialect"));
config.setProperty("hibernate.connection.driver_class", ConfigManager.getInstance().getString(Consts.CONFIG_DB_DRIVER_CLASS, "com.mysql.jdbc.Driver"));
config.setProperty("hibernate.connection.url", ConfigManager.getInstance().getString(Consts.CONFIG_DB_URL, "jdbc:mysql://localhost/photometo"));
config.setProperty("hibernate.connection.useUnicode", "true");
config.setProperty("hibernate.connection.characterEncoding", "UTF-8");
config.setProperty("hibernate.connection.username", ConfigManager.getInstance().getString(Consts.CONFIG_DB_USERNAME, "root"));
config.setProperty("hibernate.connection.password", ConfigManager.getInstance().getString(Consts.CONFIG_DB_PASSWORD, ""));
config.setProperty("hibernate.hbm2ddl.auto", ConfigManager.getInstance().getString(Consts.CONFIG_DB_HBMDDL_AUTO, "update"));
sessionFactory = config.buildSessionFactory();
}
catch (Throwable ex)
{
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory()
{
return sessionFactory;
}
}我注意到过了一段时间,这种事就开始发生了。如果我重新启动tomcat或重新部署应用程序,问题就会消失。
发布于 2017-02-07 13:37:23
您从未启动过事务,也无法获得其他事务。这就是当您调用它时会收到错误的原因:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
transaction = session.getTransaction(); // Here is the error! You can't get an active transaction, becasue there isn't even started
if(!transaction.isActive()) // transaction.isActive() is usually for closing a transction in the end
{
transaction = session.beginTransaction(); // You are starting the transaction!
}
accessToken = session.get(OAuthAccessToken.class, token);您无法获得活动事务,因为甚至还没有启动。将代码更改为:
// Non-managed environment idiom with getCurrentSession()
try {
factory.getCurrentSession().beginTransaction();
// do some work
...
factory.getCurrentSession().getTransaction().commit();
}
catch (RuntimeException e) {
factory.getCurrentSession().getTransaction().rollback();
throw e; // or display error message
}在非托管环境中启动事务的正确原因是来自Hibernate文档。
// Non-managed environment idiom with getCurrentSession()
try {
factory.getCurrentSession().beginTransaction();
// do some work
...
factory.getCurrentSession().getTransaction().commit();
}
catch (RuntimeException e) {
factory.getCurrentSession().getTransaction().rollback();
throw e; // or display error message
}
// Non-managed environment idiom with getCurrentSession() try {
factory.getCurrentSession().beginTransaction();
// do some work
...
factory.getCurrentSession().getTransaction().commit(); } catch (RuntimeException e) {
factory.getCurrentSession().getTransaction().rollback();
throw e; // or display error message }按照getTransaction()的文档,当前会话不会启动事务。
getTransaction()
Get the Transaction instance associated with this session.下面是启动事务11.2数据库事务划分的原因
数据库或系统事务边界总是必要的。在数据库事务之外,无法与数据库进行任何通信(这似乎使许多习惯于自动提交模式的开发人员感到困惑)。始终使用明确的事务边界,即使对于只读操作也是如此.
长事务对DB不利,因为在DB中生成了许多锁,会话和事务范围。
为了减少数据库中的锁争用,数据库事务必须尽可能短。长数据库事务将阻止应用程序扩展到高度并发的负载。建议不要在用户思考期间将数据库事务打开,直到工作单元完成为止。
https://stackoverflow.com/questions/41869684
复制相似问题