ORA-01002:使用@transactional时取出顺序

时间:2013-09-04 06:27:35

标签: spring oracle spring-mvc plsql mybatis

当我尝试从我的应用程序调用一个过程时出现错误 ORA-01002:fetch out of sequence

使用的技术:

  • Mybatis 3
  • Spring MVC

这里有趣的一点是,只有当我对服务类中的调用方法使用 @Transactional (org.springframework.transaction.annotation.Transactional)注释时才会出现错误。如果我删除 @Transactional ,则没有ORA错误。

我正在使用@Transactional,因为我有几个DAO注入服务。请在下面找到我的代码。

@Transactional
    public boolean saveavgFlyHrs(AverageFlyingHoursReport averageFlyingHoursReport) throws TransactionDataException {
        String status = null;
        boolean isOk = false;
        if(averageFlyingHoursReportDAO.saveavgFlyHrs(averageFlyingHoursReport)) {
            status = averageFlyingHoursReportDAO.updateCheckEff(averageFlyingHoursReport.getSubFleet());
            logger.debug("OUT_STATUS:"+status);
            if(ConstantStringUtil.SUCCESS.equalsIgnoreCase(status)) {
                isOk = true;
            } else {
                isOk = false;
            }
        }
        return isOk;
    }

任何人都应该帮助我。

1 个答案:

答案 0 :(得分:4)

ORA-01002是Oracle错误。您没有显示任何Oracle代码,因此我们必须猜测会发生什么。

当您跨FOR UPDATE光标提交时,通常会抛出此错误,例如:

SQL> CREATE TABLE TEST (ID NUMBER, c VARCHAR2(10));

Table created

SQL> INSERT INTO TEST VALUES (1, 'a');

1 row inserted

SQL> INSERT INTO TEST VALUES (2, 'b');

1 row inserted

SQL> BEGIN
  2     FOR cc IN (SELECT * FROM TEST FOR UPDATE) LOOP -- FOR UPDATE cursor
  3        UPDATE TEST SET c = UPPER(c) WHERE ID = cc.id;
  4        COMMIT; -- this will invalidate our cursor
  5     END LOOP;
  6  END;
  7  /

ORA-01002: fetch out of sequence
ORA-06512: at line 3

我可以想象,将@Transactional添加到一个工作单元将使其在成功/回滚时提交错误。所以这个代码可能是使用某种FOR UPDATE游标的更大循环的一部分。添加@Transactional时,每次调用方法时都会提交,从而使主光标无效。

如果您在回滚了一些会使其无效的更改后尝试从游标中获取,您也会遇到ORA-01002

SQL> DECLARE
  2     CURSOR cc IS SELECT * FROM TEST;
  3     rc cc%ROWTYPE;
  4  BEGIN
  5     UPDATE TEST SET c = 'c' WHERE ID = 2;
  6     OPEN cc;
  7     FETCH cc INTO rc;
  8     -- do other things
  9     ROLLBACK;
 10     FETCH cc INTO rc;
 11  END;
 12  /

ORA-01002: fetch out of sequence
ORA-06512: at line 11

这里我们的游标cc无效,因为我们已经回滚了一些影响游标中行的更改。同样,这可能是由添加@Transactional引起的,并且该方法在仍然从中获取另一个游标时回滚事务。

总之:您只应将@Transactional添加到执行不可分割的工作量的单位。如果该方法是更大事务的子方法,则它不应该自己提交/回滚。