我在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条记录中承诺以避免这种情况?
答案 0 :(得分:1)
如果您回滚,您将失去事务中的所有先前记录。如果您只想丢失具有约束异常的记录,那么您可以将每个批次的记录保存在列表中,并在批次炸弹时切换到逐个提交,然后继续批处理。
答案 1 :(得分:1)
在这种类型的用例中,您有另一项工作可以将所有数据分成100个对象,并为这些对象启动子工作。
在这种情况下,对我来说最好的事情就是抛出异常。然后主作业获得此异常,并且所有100个对象都回滚。然后,主作业可以进入这些对象的另一种模式,并重新启动每个对象的子工作。然后只有抛出异常的那个才会被保存。
这是批次的典型处理。如果一切正常,您的批处理速度很快,因为您提交了每100个对象,但是如果出现错误,您将退回到单个对象提交中,这样您就不会保存失败的对象。
但正如mericano1所说,你案件中的正确行为是商业规则的问题。
答案 2 :(得分:0)
如果你每100次插入一次,那么在第56次插入后回滚也会撤消之前的所有55次插入。
您可以在每次插入后提交,但是批量插入的行很多,这些行很慢而且不推荐。
解决方案是使用保存点。
设置保存点相对较快。它可以在每次插入后完成。设置保存点不会将任何数据写入数据库 - 您仍需要稍后提交 - 但仅在最后一个保存点之前完成回滚。
因此,在您的示例中,您提交每100行(或其他任何行)(并确保在最后一行之后),并在每行之后设置一个保存点。当出现错误并回滚动作时,只撤消错误插入,不触及其他插入。
有关说明,请参阅示例java.sql.Connection.setSavepoint,java.sql.Savepoint或here。