`

Hibernate数据库同步问题

阅读更多

此问题存在于结算单调整模块中,描述如下:结算单有主表和从表,在一个事务中,调整操作中如果将从表的记录都删掉了,此时业务上的操作应该是删除掉从表记录以后,同时删除主表的记录,由于是在同一个事务中,先删除的是从表,后删除的是主表,在删除主表之前事务比没有提交,此时,如果在删除主表之前通过一个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");
			}
分享到:
评论

相关推荐

    用Hibernate3.1实现XML和数据库的同步

    用Hibernate3.1实现XML和数据库的同步

    spring+hibernate和spring+myBatis实现连接多个数据库,同时操作的项目

    项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此。多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源。 此项目就是为了解决这个问题。

    Hibernate与数据库的触发器协同工作

     解决方案: 在执行完 Session 的相关操作后, 立即调用 Session 的 flush() 和 refresh() 方法, 迫使 Session 的缓存与数据库同步(refresh() 方法重新从数据库中加载对象)  2、update() 方法盲目地激发...

    Spring4+Hibernate4+HTML5WebSocket简单应用示例

    NULL 博文链接:https://quarterlifeforjava.iteye.com/blog/2163576

    深入浅出Hibernate中文版 part1

    8.4 XDoclet-同步Hibernate基础代码 8.5 工具的使用周期 第9章 Hibernate XDoclet模板配置 9.1 IDEA 9.2 Eclipse 第10章 Hibernate益友——iBatis 10.1 Ibatis 概述 10.2 快速起步 10.3 IBatis 基础 10.4 ...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    处于持久化状态的Java对象位于一个Session实例的缓存中,Session能根据这个对象的属性变化来同步更新数据库。 8.1 Java对象在JVM中的 生命周期 179 8.2 理解Session的缓存 181 8.2.1 Session的缓存的作用 182 ...

    hibernate 3中的缓存小结

    当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。 Session为应用程序提供了两个管理缓存的方法: evict(Object obj):从缓存中清除参数指定的持久化对象。 clear():清空缓存中所有持久化对象...

    hibernate的核心接口--Session

    Session是Hibernate中应用最频繁的接口,Session也被称为持久化管理器,它负责所有的持久化工作,负责管理持久化对象的生命周期,提供第一级别的高级缓存来保证持久化对象的数据与数据库同步

    深入浅出Hibernate中文版 part2

    8.4 XDoclet-同步Hibernate基础代码 8.5 工具的使用周期 第9章 Hibernate XDoclet模板配置 9.1 IDEA 9.2 Eclipse 第10章 Hibernate益友——iBatis 10.1 Ibatis 概述 10.2 快速起步 10.3 IBatis 基础 10.4 ...

    Android数据库应用编程——为企业开发数据驱动Android应用

    Android数据库应用编程——为企业开发数据驱动Android应用 透彻讲述如何使用内容提供器共享数据、使用适配器显示数据以及使用Web服务传输数据,介绍集成应用程序和现有企业系统、保护数据以及同步数据的方法。...

    hibernate 教程

    提交数据库事务 9.7.3. 关闭Session 9.7.4. 处理异常 9.8. 生命周期和对象图(Lifecyles and object graphs) 9.9. 拦截器(Interceptors) 9.10. 元数据(Metadata) API 10. 事务和并行...

    Hibernate使用技巧汇总

    session.Flush() 强制数据库立即同步,当用事务时,不必用flush,事务提交自动调用flush 在session关闭时也会调用flush &lt;br&gt;4. Hibernate总是使用对象类型作为字段类型 5. XDoclet专门建立了...

    精通Hibernate:对象持久化技术第二版part3

    处于持久化状态的Java对象位于一个Session实例的缓存中,Session能根据这个对象的属性变化来同步更新数据库。 8.1 Java对象在JVM中的 生命周期 179 8.2 理解Session的缓存 181 8.2.1 Session的缓存的作用 182 ...

    hibernate总结

    c) Session会在特定的时刻(清理缓存时)维护这个对象和数据库中的记录进行同步 d) 在同一个session的缓存中,具有相同OID的持久态对象,只有一个(同一个session的一缓存中,不可能同时有两个OID相同的同一个持久化类...

    hibernate的flush()、refresh()、clear()针对一级缓存的操作的区别.docx

    1 session.flush()的作用就是将session的缓存中的数据与数据库同步。 2 session.clear()的作用就是清除session中的缓存数据(不管缓存与数据库的同步)。 3.session.refresh():会强制发送select语句,以使session...

    HiberNate实体

    hibernate实体有三个状态 1、瞬时状态 对象由new操作符创建,尚未与Session关联的对象被认为处于瞬态....在修改持久状态的时候,不会去立即同步数据库,会先放入到一级缓存,当我们提交事务的时候 hibernat

    hibernate

    提交数据库事务 9.7.3. 关闭Session 9.7.4. 处理异常 9.8. 生命周期和对象图(Lifecyles and object graphs) 9.9. 拦截器(Interceptors) 9.10. 元数据(Metadata) API 10. 事务和并行...

    基于javaweb旅游网系统SSH的毕业设计,SSH架构,即SpringMVC+Spring+Hibernate+Mybatis

    该毕业设计采用SSH架构,即SpringMVC+Spring+Hibernate+Mybatis架构,实现了旅游网站的登录注册、旅游线路查询、旅游景点查询、用户订单管理、购物车功能等模块。 系统的主要技术选型有:前端使用HTML5、CSS3、...

    superdock:用于symfony,drupal和wordpress的本地环境,从中同步目录和数据库,并使用版本管理来部署代码

    用于symfony,drupal和wordpress的本地环境,与目录之间的目录和数据库同步,以及使用版本管理来部署代码 安装 安装要求: 本地环境 CPU稳定性和更好的Hibernate方式 Docker撰写 虚拟箱 文件同步可加快页面加载...

Global site tag (gtag.js) - Google Analytics