此问题存在于结算单调整模块中,描述如下:结算单有主表和从表,在一个事务中,调整操作中如果将从表的记录都删掉了,此时业务上的操作应该是删除掉从表记录以后,同时删除主表的记录,由于是在同一个事务中,先删除的是从表,后删除的是主表,在删除主表之前事务比没有提交,此时,如果在删除主表之前通过一个load方法来重新取数据库中明细数据,这时取到的数据应该是在数据中的数据(此时事务还没有提交,所以数据库的数据还是在删除明细的状态的数据),然后根据此次查询到的数据判断是否已经将明细的数据全部删除完,这个判断就会出错,查询到的明细并不是最新的数据,后续操作又根据数据的历史状态来确定,因此问题不可避免。要解决此问题,一个比较简单的方法就是在完成删除明细的操作之后应该马上同步数据到数据库,这样就不会有问题了,当然同步数据到数据库,势必会影响性能,尤其是在数据量比较大的情况之下不可避免。
另外要提到的一点是:在tomcat上运行修改之前的代码是没有上述提到的问题的,在weblogic上运行是存在上述问题的,由此初步推断同一种load数据库数据的方法在tomcat环境中是直接从内存中获取的,而weblogic环境中数据则是从数据库中获取到的(此观点只是根据实际情况推测,没有深究)
具体代码如下:
这是修改之前的代码(虚线的地方是要改动的代码)--
for (ParamsForAdjust paramsForAdjust2 : paramsForAdjust) {
if (paramsForAdjust2.getHandOverNo() != null) {
if (paramsForAdjust2.getSeqPolicy() != null
&& !paramsForAdjust2.getSeqPolicy().equals(null)) {
policy = policyDao.getPolicy(paramsForAdjust2
.getSeqPolicy());
policy.setHandoverno(paramsForAdjust2.getHandOverNo());
policyDao.update(policy, lastdate);
// 新增保单到结算单明细
handoverdetail.setOpstatus("0");
handoverdetail.setOpdate(new Date());
handoverdetail.setOpcode(opcode);
handoverdetail.setPolicyno(policy.getPolicyno());
handoverdetail.setSeqpolicy(policy.getSeqpolicy());
handoverdetail.setSubcompany(policy.getSubcompany());
handoverdetail.setHandoverno(paramsForAdjust2
.getHandOverNo());
handOverDetailDao.addHandOverDetail(handoverdetail);
} else if (paramsForAdjust2.getSeqHandOverdetail() != null) {
// 更新保单
handoverdetail = handOverDetailDao
.getHandOverDetail(paramsForAdjust2
.getSeqHandOverdetail());
policy = policyDao.getPolicy(handoverdetail
.getSeqpolicy());
policy.setHandoverno(null);
policyDao.update(policy, lastdate);
// 结算单调整对结算单明细的操作--删除结算单明细
// 取消明细
handOverDetailDao.cancelHandOverDetail(paramsForAdjust2
.getSeqHandOverdetail());
} else {
throw new BusinessException("操作失败:结果集数据不正确!");
}
} else
throw new BusinessException("操作失败:取消操作获取的信息不全--未获取到结算单号!");
}
//---------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
List list = handOverDetailDao
.getHandOverDetailbyHandOverno(paramsForAdjust.get(0)
.getHandOverNo());
if (list != null && list.size() == 0) {
HandOver handover = handOverDao.getHandOver(
paramsForAdjust.get(0).getHandOverNo()).get(0);
handOverDao.deleteHandOver(handover.getSeqhandover());
// if (handover == null) {
// throw new BusinessException("操作失败:获取结算单<?>数据出错!");
// }
// handover.setOpstatus("3");
}
这是修改后的代码(虚线的地方是改动后的代码,其他没有变化):
for (ParamsForAdjust paramsForAdjust2 : paramsForAdjust) {
if (paramsForAdjust2.getHandOverNo() != null) {
if (paramsForAdjust2.getSeqPolicy() != null
&& !paramsForAdjust2.getSeqPolicy().equals(null)) {
policy = policyDao.getPolicy(paramsForAdjust2
.getSeqPolicy());
policy.setHandoverno(paramsForAdjust2.getHandOverNo());
policyDao.update(policy, lastdate);
// 新增保单到结算单明细
handoverdetail.setOpstatus("0");
handoverdetail.setOpdate(new Date());
handoverdetail.setOpcode(opcode);
handoverdetail.setPolicyno(policy.getPolicyno());
handoverdetail.setSeqpolicy(policy.getSeqpolicy());
handoverdetail.setSubcompany(policy.getSubcompany());
handoverdetail.setHandoverno(paramsForAdjust2
.getHandOverNo());
handOverDetailDao.addHandOverDetail(handoverdetail);
} else if (paramsForAdjust2.getSeqHandOverdetail() != null) {
// 更新保单
handoverdetail = handOverDetailDao
.getHandOverDetail(paramsForAdjust2
.getSeqHandOverdetail());
policy = policyDao.getPolicy(handoverdetail
.getSeqpolicy());
policy.setHandoverno(null);
policyDao.update(policy, lastdate);
// 结算单调整对结算单明细的操作--删除结算单明细
// 取消明细
handOverDetailDao.cancelHandOverDetail(paramsForAdjust2
.getSeqHandOverdetail());
} else {
throw new BusinessException("操作失败:结果集数据不正确!");
}
} else
throw new BusinessException("操作失败:取消操作获取的信息不全--未获取到结算单号!");
}
//-------------------------------------------------------------------------------------------------
//同步结算单明细操作到数据库中,如果不同步,以下的查询不会取到此次操作的最新数据
handOverDetailDao.flushDataForHandOverDetail();
//-------------------------------------------------------------------------------------------------
List list = handOverDetailDao
.getHandOverDetailbyHandOverno(paramsForAdjust.get(0)
.getHandOverNo());
if (list != null && list.size() == 0) {
HandOver handover = handOverDao.getHandOver(
paramsForAdjust.get(0).getHandOverNo()).get(0);
handOverDao.deleteHandOver(handover.getSeqhandover());
// if (handover == null) {
// throw new BusinessException("操作失败:获取结算单<?>数据出错!");
// }
// handover.setOpstatus("3");
}
分享到:
相关推荐
### Hibernate使用缓存时的数据同步问题详解 #### 引言 在现代软件开发中,ORM框架如Hibernate被广泛应用于数据库操作,以简化Java应用程序与数据库之间的交互。然而,使用Hibernate时,缓存机制的合理配置对于...
《hibernate数据库映射例子.zip》这个压缩包包含了几个基于Hibernate框架的数据库映射示例,旨在帮助初学者理解并掌握如何在实际项目中应用Hibernate进行数据持久化操作。Hibernate是一个强大的Java对象关系映射...
### 使用Hibernate 3.1实现XML与数据库的同步:深入解析与实践 #### 概述 Hibernate,作为一套开源的对象关系映射(ORM)框架,为Java开发者提供了强大的数据库交互能力。自3.1版本起,Hibernate引入了XML到数据库...
在Java世界中,Hibernate是一个非常流行的持久化框架,它简化了数据库操作,使得开发者可以更加专注于业务逻辑而不是底层数据访问的细节。本训练主要关注在使用Hibernate时如何处理与各种数据库字段类型的映射,这...
通过这些映射文件,Hibernate能够自动创建或更新数据库结构,使得模型与数据库保持同步。 二、Hibernate生成数据库步骤 1. 创建实体类:首先,你需要定义Java实体类,这些类代表了数据库中的表。每个类对应一个...
**标题:“Hibernate数据库连接”** **一、Hibernate概述** Hibernate是一个强大的开源对象关系映射(ORM)框架,它简化了Java应用程序与关系数据库之间的交互。它允许开发人员使用面向对象的方式来操作数据库,...
在使用Eclipse Hibernate Synchronizer时,开发者可以快速地将数据库结构映射到Java持久化类(POJOs),同时也能将这些类反向同步到数据库中。这在进行敏捷开发和数据库频繁调整时非常有用,因为它允许你在设计阶段...
此外,反向工程不仅适用于创建表,还可以用于更新数据库结构,比如当实体类发生变化时,可以通过反向工程同步数据库表结构。只需确保`hibernate.reveng.xml`和实体类的更改一致,再次运行`SchemaExport`即可。 总之...
在IT行业中,ORM(Object-Relational Mapping)框架如Hibernate,为开发者提供了便利,将数据库中的表...在实际项目中,结合Maven或Gradle的生命周期,可以在每次构建时自动更新Java Bean,确保与数据库结构保持同步。
2. **Hibernate ORM**:Hibernate是一个流行的数据持久化库,它允许开发者将Java对象直接映射到数据库表,减少了SQL的编写工作。在Spring应用中,通常使用Spring Data JPA或Hibernate来处理数据库交互。 3. **...
在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库,而无需关心底层SQL语句。在Hibernate 3.0版本中,虽然XML配置文件仍然是主要的配置方式,但已经...
本篇将详细讲解如何在Java项目中结合SpringBoot和Hibernate进行双数据源配置,以满足对MySQL数据库的高效管理。 首先,我们要明白什么是双数据源配置。双数据源配置是指在一个应用中同时管理两个或更多的数据源,每...
7. 数据迁移与同步:在某些场景下,可能需要实现在两个数据库间的数据迁移或实时同步,这可能需要用到额外的工具或中间件,如Flyway、Liquibase等。 总的来说,"SpringBoot+Hibernate+MySQL+SQLServer双数据源"项目...
本篇文章将深入探讨在使用Hibernate时可能会遇到的线程同步问题,以及 Hibernate 中的 session.get() 和 session.load() 方法的异同。 一、Hibernate的并发控制 在多线程环境下,多个线程同时访问和修改数据库记录...
`merge()`方法用于将游离态对象合并到持久化状态,它的作用是将 Detached 对象的最新状态同步到数据库。 8. **对象状态转换**: - Hibernate支持四种对象状态:Transient(瞬时态)、Persistent(持久态)、...
1. **创建数据库模型**:定义数据库表结构和数据模型,这通常是通过ORM(对象关系映射)框架如Hibernate或MyBatis完成的。 2. **版本记录**:在每次数据库结构更改时,创建一个新的版本。这可以通过脚本文件(如SQL...
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式来操作数据库。在Hibernate中,主键生成策略是确保实体类中的主键字段具有唯一标识的关键部分。以下是对Hibernate主键生成策略的...
标题中的“ExtJs2.0 SSH 实现简单结构与上传文件 数据库同步树形结构”表明了这个项目的核心特性。首先,`ExtJs2.0`用于构建用户界面,尤其是树形结构展示,这在数据管理中十分常见,如组织架构、文件目录等。树形...
例如,当你已经有了一个完整的数据库结构,只需要运行Middlegen-Hibernate,就可以得到一套完整的Java持久化模型,再配合hibernate-extensions,可以直接将这些模型同步到数据库,或者更新数据库以适应模型的变化。...
《HibernateSynchronizer 3.1.9:数据库与对象模型同步的利器》 HibernateSynchronizer是一款基于Java的开源工具,专为开发者设计,...通过合理使用,开发者可以专注于业务逻辑的开发,而无需担心数据库同步的问题。