web-dev-qa-db-ja.com

例外ORA-08103:Hibernateのsetfetchsizeの使用時にオブジェクトが存在しません

私はHibernateを使用しています。約1000000レコードをフェッチする必要があり、タイムアウト例外が発生します。したがって、6000レコードに対してsetfetchsizeを使用しているため、操作は6000レコードごとに複数のトランザクションに分散されます。

すべてを取得するには、約21時間かかります。

しかし、その間にレコードを取得するときに、フェッチされたレコードの1つを誰かが削除した場合、ORA-08103: object no longer exists

次に、取得中に削除されたオブジェクトをスキップします。これどうやってするの?

12
Barney

カーソルは、ON COMMIT DELETE ROWSオプションで作成されたグローバル一時テーブル(GTT)に基づいて開かれる可能性が高いです。そして、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:エラーに直面することを恐れずに、そのテーブルに基づくカーソルからデータを安全にフェッチできます。

15
Nick Krasnov

1週間苦労した後、ようやく問題を修正しました。

解決策:ほとんどの場合、ON COMMIT DELETE ROWSオプションを使用して作成されたグローバル一時テーブル(GTT)に基づいてカーソルが開かれます。また、ORA-08103:オブジェクトが存在しないエラーの原因は、削除ステートメントの直後に続くコミットステートメントです。 DBAチームはコミット保持行のようにGTTを変更することに同意しなかったため、最後にコードベースをJava Service Layer [Implementing 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;
   }
}
0
user1765387