处理请求后,数据保留在休眠的会话对象中



我最近开始用SOAP网络服务,Spring和Hibernate做一个项目。

我面临以下问题:

我们使用 SOAP UI 发送请求来测试我们的代码。我写了一个处理账单的服务。基本上有 2 种服务,一种创建账单,另一项处理账单。

我们有一个名为BillTb的表。在处理账单之前,我们会检查账单的状态。如果账单状态为 3(待处理),我们会处理它。如果它不等于 3,我们不处理它。处理帐单后,我们将状态更改为 4(已处理)。

现在,如果账单状态为 3,我们在其他表中执行多个条目,最后,状态更改为 4。

如果在处理之间,如果处理失败,我们需要还原所有这些条目。因此,我们在事务中调用这些条目。

带有休眠代码的 DAO 层如下:

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;
public class BillDAOImpl implements BillDao {
...
...
...
int pendingStatus = 3;
int processedStatus = 4;
Session session = null;
for(int id: ids){
Bill bill = null;

try{
session = entityManager.unwrap(Session.class);
bill= entityManager.find(Bill.class, id);
session.getTransaction().begin();
if(bill.status() != pendingStatus ){
System.out.println("The bill is already processed");
continue;
}
...
...
bill.setStatus(processedStatus);
entityManager.persist(bill);
session.getTransaction().commit();
} catch(Exception e){
}
}


}

现在的问题是,一旦账单状态从 3 更改为 4,如果我通过在数据库中触发更新查询再次将状态更改为 3,它应该再次工作,但不知何故,它只将状态读取为 4。

如果我关闭服务器,然后再次执行请求,那么它适用于相同的条目。

其他事务相关参数设置为:

<property name="hibernate.cache.use_query_cache" value="false" />

<bean id="projectEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceXmlLocation="classpath*:META-INF/persistence.xml"
p:persistenceUnitName="persistenceUnit" p:loadTimeWeaver-ref="loadTimeWeaver"
p:jpaVendorAdapter-ref="jpaVendorAdapter" p:jpaDialect-ref="jpaDialect"
p:dataSource-ref="datasourceBean">
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup
</prop>
<prop key="hibernate.transaction.flush_before_completion">false</prop>
...
...             
<prop key="hibernate.connection.isolation">3</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
</props>
</property>
</bean>

所以在这里,会话似乎以某种方式存储账单对象,当我直接在数据库中更新账单对象时,它会存储过时的数据。那么在这种情况下应该怎么做。我应该在方法结束时清除会话吗?

您应该在事务内部执行查询,并记住每次都提交事务(如果触发 continue,则省略)。

其实我会这样写:

for(int id: ids){
Bill bill = null;
Transaction tx = session.getTransaction();
tx.begin();
try{          
bill= entityManager.find(Bill.class, id);
if(bill.status() != pendingStatus ){
System.out.println("The bill is already processed");
tx.commit();
continue;
}
bill.setStatus(processedStatus);
entityManager.persist(bill);   
session.flush();
tx.commit();
}catch(Exception e){
tx.rollback();
throw e;
}
}

相关内容

  • 没有找到相关文章

最新更新