【问题标题】:Hibernate Stateless Session best way to handle errors?Hibernate Stateless Session 处理错误的最佳方式?
【发布时间】:2012-08-25 04:43:06
【问题描述】:

我在 Play Framework 1.2.4 项目中使用无状态会话进行批处理作业。

我插入和更新行非常好,但我不知道发生异常时该怎么办。这是我的代码:

try{
      statelesssession.insert(someobject);
   }
catch(ConstraintViolationException e)  //It happens from time to time dont ask me why..
   {
      ??????transaction.rollback();????? THATS MY CONCERN
   }
finally{
      transaction.commit();
   }

我需要知道的是,我在每 100 次插入时提交数据。我想知道,如果在第 56 条记录中发生约束违规并且事务进行回滚,我是否也会丢失其他 55 条记录?

如果是,我必须在约束违反异常中做什么?还是我应该在每 1 条记录中承诺以避免这种情况?

【问题讨论】:

  • 我认为您应该向您的客户提出这个问题,而不是在这里.. 但是如果您在第 56 条记录处回滚而不提交 您将丢失之前的更改直到最后提交。
  • 坦克,我不确定它是否只是回滚相应的数据或所有批次。
  • 我还有一个问题,当我遇到异常时,我认为该对象仍在内存中,因为我的内存使用率越来越高,直到内存不足。发生异常时如何从内存中擦除该数据?

标签: hibernate playframework bulkinsert stateless-session


【解决方案1】:

如果您回滚,您也将丢失事务中的所有先前记录。如果您只想丢失具有约束异常的记录,那么您可以将每个批次的记录保存在一个列表中,并在批次爆炸时切换为逐个提交,然后继续执行批次。

【讨论】:

    【解决方案2】:

    在这种类型的用例中,您有另一个作业将所有数据切割成 100 个对象的片段,并为这些对象启动子作业。

    在这种情况下,对我来说最好的办法就是抛出异常。然后主作业得到这个异常,你所有的 100 个对象都回滚了。然后主作业可以进入这些对象的另一种模式并重新启动每个对象的子作业。那么只有抛出异常的那个不会被保存。

    这是典型的批处理。如果一切正常,您的批处理速度很快,因为您每 100 个对象提交一次,但如果出现错误,您会退回到单个对象提交,因此您不会保存失败的对象。

    但正如 mericano1 所说,在您的情况下,正确的行为是业务规则问题。

    【讨论】:

    • 所以这里还有另一个问题。发生异常时,java.exe 的内存使用量正在增加(我猜 java 将对象保留在内存中)。发生异常时回收该数据的最佳方法是什么?
    • 只要您没有对对象的引用,gc 将自动执行此操作。要检查 java 内存使用情况,不要使用系统工具进行跟踪,而是使用特定工具(如 visualvm)来跟踪堆使用情况的演变
    【解决方案3】:

    如果您每 100 次插入提交一次,那么在第 56 次插入之后的回滚也会撤消之前的所有 55 次插入。

    您可以在每次插入后提交,但要分批插入非常多的行,这很慢,因此不推荐。

    解决方案是使用保存点。

    设置保存点相对较快。可以在每次插入后完成。设置保存点不会将任何数据写入数据库 - 您仍然需要稍后提交 - 但只会在最后一个保存点之前进行回滚。

    因此,在您的示例中,您每 100 行(或其他)提交一次(并且肯定在最后一行之后),并在每一行之后设置一个保存点。当出现错误并回滚操作时,只有错误的插入被撤消,其他的不会被触及。

    有关描述,请参见例如 java.sql.Connection.setSavepoint、java.sql.Savepoint 或 here

    【讨论】:

      猜你喜欢
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2011-06-09
      • 2016-08-21
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多