在MVC请求完成之前,Hibernate事务不会启动

我正在使用spring MVC 3和Hibernate 3.6,使用Spring tx来管理hibernate事务,

现在我正在向控制器发出一个ajax请求,当控制器返回一个值时,我导航到另一个页面,我继续检查控制器,直到返回值。

这个控制器方法调用也有一些数据库事务要做,而我想要做的是在每个事情完成并且数据库tx完成并且一切都很好时导航,但是会发生什么是hibernate的persist()或save( )方法退出但事务未启动。

我调试了代码并发现spring对事务执行了某种队列,直到对控制器的请求完成为止,这意味着它不会执行事务,而是表示方法已完成,并对事务进行排队然后执行此操作后来。

编辑

这是我的相关代码

$("#kse_search").click(function (e){ $.get('updateProgress',function(data){ if(data == 'NaN' || data < 0){ $(".modal-backdrop").removeClass("hidden"); $("#bar_carrier").removeClass("hidden"); $.get('kse.htm'); interval = setInterval("ajaxP()",1000); }else{ alert("There is an ongoing query for the same session, please wait until its finished"); } }); }) // updata progress function ajaxP(){ $.get('updateProgress',function(data){ datain = data; if(data != 404){ var bar = "
"; if($("#bar").length == 0){ $("#bar_carrier").html(bar); } if(data < 100){ $("#bar").css("width",data+"%"); $("#please_wait").html("" +Math.round(data)+"% complete"); } else if(data >= 100 && (data == 203 || data == 204)){ var please_wait = "Finalizing and saving to database please wait<i class='icon-spinner icon-spin'"; if($("#please-wait-font").length == 0) { $("#bar").css("width",data+"%"); } else{ $("#please_wait").html(please_wait); $("#bar").css("width",data+"%"); } clearInterval(interval); setTimeout('ajaxProgress()',2*60*1000); } } else{ clearInterval(interval); $("#bar_carrier").html("

market is still open please try again later

") } }) }

这是我的控制器有关更新进度和初始请求

 @RequestMapping("/kse.htm") public @ResponseBody String kseData(Model model){ parser.setExchange("kse"); boolean choice = parser.start(); return String.valueOf(choice); } @RequestMapping("/updateProgress") public @ResponseBody String progress(Model model){ float progress = parser.getProgress(); if(progress != 404 && progress != 204 && progress != 203){ return String.valueOf((progress/parser.getTotalProgress())*100); } else{ return String.valueOf(progress); } } 

这是我的dao函数中的保存函数

 public boolean add(T entity) { getSession().save(entity); return true; } 

这是我的getSession()工厂自动assembly

 public Session getSession(){ return (this.factory.getCurrentSession()==null)? this.factory.openSession(): this.factory.getCurrentSession(); } 

这就是我的事务通过xml配置管理的方式

                           

控制器调用解析器的方法(一个会话范围的bean)来执行开始执行,解析器的函数是一个Async,它依次调用dao的另一个方法来执行保存,每个东西都工作正常, dao的方法退出然后发送到更新进度的所有请求完成后,事务开始了,他们是否懒得完成? 我想要做的就是在我到达save方法或任何方法时进行转换。

编辑2

好的,这是我更新进度或重要部分的方法

 if(found != null){ this.tempData = found; notFound = dataChecker.checkData(found); if(notFound.size() == 0){ saveAllData(addDuplicates(dataChecker.getModifiedHolders())); this.progress = 204; return true; } else { this.progress = 203; return false; } } return false; 

现在我注意到了一些更糟糕的行为,dataChecker负责填充未发现的List,并且在这样做时它将很多数据保存到数据库,现在不应该返回进度,直到所有这些完成,

但是会发生的是,进度返回为204,就好像datachecker已经完成并且数据为空。

然后事务开始发生,像datachecker只将它们添加到队列中。

但是在我使用空的notFound导航到另一个页面之后会发生这种情况,并且在事务完成后刷新页面并且每件事都完成后,页面现在都有数据。

请注意,默认的Spring事务管理是特定于线程的 。 每个事务状态(及其数据库连接)都存储在ThreadLocal变量( TransactionSynchronizationManager )中。

这意味着,如果您在一个请求中启动事务(假设线程为http-0 )然后您尝试通过从不同线程(假设为http-1 )进行的数据库查询来检查进度,那么您将无法成功。 第二个线程将拥有自己的事务,并且在第一个线程提交更改之前,它不会看到绑定到第一个线程的事务中的数据。

您实际需要的是在某个变量中定期存储和更新第一个线程( http-0 )的进度,然后可以由其他线程读取。


更新1:更具体一点 – 您的parser.getProgress() 不得调用数据库以获取正确的进度信息。


更新2:刚刚注意到你的getSession()方法。 自己打开新会话是一个严重的错误 。 这应该由Spring的事务管理器完成。 如果sessionFactory.currentSession()返回null则应抛出exception。