1

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

使用的技术:

  • 米巴蒂斯3
  • 春季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;
    }

任何人请帮我解决这个问题。

4

1 回答 1

5

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到做不可分割的工作量的单位。如果该方法是更大事务的子方法,则不应自行提交/回滚。

于 2013-09-04T08:25:38.780 回答