当我尝试从我的应用程序调用一个过程时出现错误 ORA-01002:fetch out of sequence
使用的技术:
这里有趣的一点是,只有当我对服务类中的调用方法使用 @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;
}
任何人都应该帮助我。
答案 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
添加到执行不可分割的工作量的单位。如果该方法是更大事务的子方法,则它不应该自己提交/回滚。