0

我正在我的 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 条记录中承诺以避免这种情况?

4

3 回答 3

1

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

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

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

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

于 2012-08-31T06:29:17.137 回答
1

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

于 2012-08-30T19:01:25.757 回答
0

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

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

解决方案是使用保存点。

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

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

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

于 2012-08-31T10:32:53.833 回答