我有一个使用Hibernate 4和Spring Transactions的Spring 3.2应用程序.所有方法都运行良好,我可以正确访问数据库以保存或检索实体.然后,我介绍了一些多线程,并且由于每个线程都访问了db,我从Hibernate收到以下错误:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
Run Code Online (Sandbox Code Playgroud)
我从网上读到我要添加<prop key="hibernate.current_session_context_class">thread</prop>到我的Hibernate配置中,但是现在每次我尝试访问db时都会得到:
org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction
Run Code Online (Sandbox Code Playgroud)
但是我的服务方法是注释的@Transactional,并且在添加之前一切正常<prop key="hibernate.current_session_context_class">thread</prop>.
为什么没有交易,尽管方法是用@Transactional注释的?我怎么解决这个问题?
这是我的Hibernate配置(包括会话上下文属性):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- Hibernate session factory -->
<bean
id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" >
<ref bean="dataSource" />
</property>
<property name="hibernateProperties" >
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
<property name="annotatedClasses" …Run Code Online (Sandbox Code Playgroud) 我得到了一个
org.hibernate.TransactionException: nested transactions not supported
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1395)
at com.mcruiseon.server.hibernate.ReadOnlyOperations.flush(ReadOnlyOperations.java:118)
Run Code Online (Sandbox Code Playgroud)
抛出该异常的代码.我从一个运行无限的线程调用flush,直到有数据要刷新.
public void flush(Object dataStore) throws DidNotSaveRequestSomeRandomError {
Transaction txD;
Session session;
session = currentSession();
// Below Line 118
txD = session.beginTransaction();
txD.begin() ;
session.saveOrUpdate(dataStore);
try {
txD.commit();
while(!txD.wasCommitted()) ;
} catch (ConstraintViolationException e) {
txD.rollback() ;
throw new DidNotSaveRequestSomeRandomError(dataStore, feedbackManager);
} catch (TransactionException e) {
txD.rollback() ;
} finally {
// session.flush();
txD = null;
session.close();
}
// mySession.clear();
}
Run Code Online (Sandbox Code Playgroud)
编辑:我在一个独立的线程中调用flush,因为数据存储列表包含数据.从我看到它的同步操作调用到flush,所以理想情况下flush应该不会返回,直到事务完成.我希望这种方式是我想要的最少.由于它是一个完成其工作的独立线程,所以我关心它是同步操作.现在我的问题是,txD.com发出异步操作吗?在交易有机会完成之前是否返回.如果是,是否有办法提交"等待"直到事务完成?
public void run() {
Object dataStore …Run Code Online (Sandbox Code Playgroud) 我需要验证数据库中是否存在记录,但无论我传递给以下代码的id如何,它都不会显示任何内容.记录是否存在.
session = HibernateUtil.getSession();
session.beginTransaction();
Query q = session.createQuery("select count(*) from Users where id = :id");
q.setInteger("id", id);
Integer count = (Integer)q.uniqueResult();
if(count > 0) {
System.err.println(">");
}
else {
System.err.println("<");
}
session.getTransaction().commit();
session.close();
Run Code Online (Sandbox Code Playgroud)
我也使用了以下代码,但仍然有同样的问题
try{
session = HibernateUtil.getSession();
session.beginTransaction();
Users users = null;
users = (Users) session.load(Users.class, id);
}catch(Exception e){
System.err.println("<");
}
Run Code Online (Sandbox Code Playgroud)