Исключение ORA-08103: объект больше не существует при использовании setfetchsize Hibernate

Я использую Hibernate. Мне нужно собрать около 1000000 записей, и это вызовет исключение тайм-аута. Поэтому я использую setfetchsize для 6000 записей, так что он будет распределять операцию по нескольким транзакциям каждый из 6000 записей.

Для получения всего потребуется около 21 часа.

Но тем временем, получая записи, если кто-то удаляет одну из записей, которые должны были быть получены, я получаю ORA-08103: object no longer exists .

Теперь я хочу пропустить этот объект, который удаляется при извлечении. Как я могу это сделать?

Скорее всего, курсор открывается на основе глобальной временной таблицы (GTT), которая была создана с опцией ON COMMIT DELETE ROWS . И причина ORA-08103: object no longer exists Ошибка – это оператор commit который следует сразу после инструкции delete . Вот простой пример:

  SQL> declare 2 type t_recs is table of number; 3 l_cur sys_refcursor; -- our cursor 4 l_rec t_recs; 5 6 begin 7 8 -- populating a global temporary table GTT1 with sample data 9 insert into GTT1(col) 10 select level 11 from dual 12 connect by level <= 1000; 13 14 open l_cur -- open a cursor based on data from GTT1 15 for select col 16 from GTT1; 17 18 -- here goes delete statement 19 -- and 20 commit; <-- cause of the error. After committing all data from GTT1 will be 21 -- deleted and when we try to fetch from the cursor 22 loop -- we'll face the ORA-08103 error 23 fetch l_cur -- attempt to fetch data which are long gone. 24 bulk collect into l_rec; 25 exit when l_cur%notfound; 26 end loop; 27 28 end; 29 / ORA-08103: object no longer exists ORA-06512: at line 24 

Восстановление глобальной временной таблицы с предложением on commit preserve rows позволяет безопасно извлекать данные из курсора, основанного на этой таблице, не опасаясь столкнуться с ошибкой ORA-08103:

После одной недели борьбы я исправил проблему:

Решение. Скорее всего, курсор открывается на основе глобальной временной таблицы (GTT), которая была создана с опцией ON COMMIT DELETE ROWS. И причина ORA-08103: объект больше не существует. Ошибка – это оператор фиксации, который следует сразу после инструкции delete. Команда DBA не согласилась изменить GTT как на фиксацию сохраненных строк, поэтому, наконец, я добавил базу кода в Java Service Layer [Реализация Spring – Programmatic Transaction]

 package com.test; import java.util.List; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; public class StudentJDBCTemplate implements StudentDAO { private DataSource dataSource; private JdbcTemplate jdbcTemplateObject; private PlatformTransactionManager transactionManager; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; this.jdbcTemplateObject = new JdbcTemplate(dataSource); } public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } public void create(String name, Integer age, Integer marks, Integer year){ TransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(def); try { String SQL1 = "insert into Student (name, age) values (?, ?)"; jdbcTemplateObject.update( SQL1, name, age); // Get the latest student id to be used in Marks table String SQL2 = "select max(id) from Student"; int sid = jdbcTemplateObject.queryForInt( SQL2 ); String SQL3 = "insert into Marks(sid, marks, year) " + "values (?, ?, ?)"; jdbcTemplateObject.update( SQL3, sid, marks, year); System.out.println("Created Name = " + name + ", Age = " + age); transactionManager.commit(status); } catch (DataAccessException e) { System.out.println("Error in creating record, rolling back"); transactionManager.rollback(status); throw e; } return; } public List<StudentMarks> listStudents() { String SQL = "select * from Student, Marks where Student.id=Marks.sid"; List <StudentMarks> studentMarks = jdbcTemplateObject.query(SQL, new StudentMarksMapper()); return studentMarks; } }