2

私のコードでは、バッチ挿入を行っています。たとえば、挿入する行が 5 つあり、そのうちの 1 つが挿入に失敗したとします。次に、休止状態ですべての行が挿入されないようにします。
私の場合、エラーを含まない他の 4 つのレコードを挿入したいと考えています。これは休止状態で可能ですか?
以下は私のコードの簡略版です。

void save() {
  Session session1 = HibernateUtil.getSessionFactory().openSession();
  Transaction transaction = session1.beginTransaction();

  for (int i = 0; i < 5; i++) {
    BatchSizeConf r = new BatchSizeConf();//This is my entity
    r.setId(i);
    r.setDispatchType("Disp");
    r.setBatchSize(500);
    Serializable z = session1.save(r);
    System.out.println(z);//prints ids
  }

  session1.flush();
  session1.clear();
  session1.getTransaction().commit();
  session1.close();
}

編集


以下の回答に従って、コードを変更し、主な問題を解決しました。今私のコードはこのようなものです。

void save() {
  for (int i = 0; i < 5; i++) {
    Session session1 = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = session1.beginTransaction();

    BatchSizeConf r = new BatchSizeConf();//This is my entity
    r.setId(i);
    r.setDispatchType("Disp");
    r.setBatchSize(500);

    try {
      session1.save(r);
      transaction.commit();
    } catch (HibernateException e) {
      System.out.println("Failed: " + i);
    }

    session1.flush();
    session1.clear();
    session1.close();
  }
}

I さて、あと2つ質問があります。

  1. 上記のように複数のセッション オブジェクトを作成しても問題ありませんか? (私は100000以上のレコードを持っています。)
  2. flush()上記のように、clear()およびclose()メソッドを呼び出す必要がありますか?
4

3 に答える 3

1

それは不可能です。トランザクションは例外によってロールバックとしてマークされます。

行をチャンクに分割し、各チャンクごとに単一のトランザクションを設定しないのはなぜですか?

このドキュメントを見てくださいtransaction-demarcation-exceptions

Session が例外 (SQLException を含む) をスローした場合は、すぐにデータベース トランザクションをロールバックし、Session.close() を呼び出して、Session インスタンスを破棄します。Session の特定のメソッドは、セッションを一貫した状態のままにしません。Hibernate によってスローされた例外は、回復可能として扱うことはできません。最終ブロックで close() を呼び出して、セッションが閉じられることを確認します。

于 2013-03-02T07:52:17.593 に答える
1

このようなことができます

Transaction tx = session.beginTransaction();
...
for (BatchSizeConf  b: BatchSizeConfList) {
    ...
    tx.commit();
}

Avaoid トランザクションの例外を参照してください

于 2013-03-02T09:00:07.947 に答える
0

Yes.. We can do.. See this code.

public List<RecordErrorStatus> persistBatch(ArrayList<?> domainRecords) {

        List<RecordErrorStatus> fedRecordErrorStatusList = new ArrayList<RecordErrorStatus>();
        Session session = getSession();
        Transaction tx = session.beginTransaction();
        long rowCount = 0;
        boolean insertionFailed=false;
        for (Object object : domainRecords) {
            rowCount++;
            try {
                System.out.println("Inserting Record:"+rowCount+object);
                session.persist(object); // Persist the given transient instance
                if (! this.rollBackOnFail) {
                    tx.commit();
                    tx = session.beginTransaction();
                }
            } catch (Exception e) {
                e.printStackTrace();
                RecordErrorStatus feedRecordStatus = new RecordErrorStatus();
                feedRecordStatus.setRowNumber(String.valueOf(rowCount));
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                String exceptionAsString = sw.toString();
                feedRecordStatus.setErrorDescription(exceptionAsString);
                fedRecordErrorStatusList.add(feedRecordStatus);
                insertionFailed =true;
                tx.rollback(); //Rollback the current record..
                session.clear();//Clear the seesion.. If not, throws Nested Transaction not allowd...
                tx = session.beginTransaction();//Start again..
            } 
        }
        if (this.rollBackOnFail && insertionFailed && ! tx.wasRolledBack()) {
            tx.rollback();
            System.out.println("Rollback");
        } 
        return fedRecordErrorStatusList;
    }

于 2015-03-31T03:49:18.837 に答える