2017-08-14 84 views
0

私は、Oracle DBとHibernateとのJavaEE/JPA管理トランザクションを使用しており、何らかのネストされたトランザクションを達成する必要があります。私が学んだ限り、そのようなことは箱からサポートされていませんが、私はその目的のためにセーブポイントを使用できるはずです。私は次のことを試してみたhttps://stackoverflow.com/a/7626387/173689によって示唆されるようにセーブポイント/ネストされたトランザクションにHibernate Session.doWork(...)を使用する方法?

connection.rollback(before)
@Transactional(value = TxType.REQUIRES_NEW) 
public boolean doImport(Import importer, Row row) throws ImportRowFailedException { 
    // stripped code ... 
    // We need to try different possibilities from which one may succeed... 
    // ...former failures must be rolled back! 
    for (Possibility poss : importer.getPossibilities()) { 
     if (this.tryPossibility(poss, row)) break; 
    } 
    // stripped code ... 
} 

public boolean tryPossibility(Possibility possibility, Row row) { 
    try { 
     Session session = this.em.unwrap(Session.class); 
     session.doWork(new Work() { 
      @Override 
      public void execute(Connection connection) throws SQLException { 
       Savepoint before = connection.setSavepoint(); 
       if (!possibility.importRow(row)) { 
        connection.rollback(before); 
        throw new ImportRowFailedException(); 
       } 
      } 
     }); 
    } 
    catch (ImportRowFailedException ex) { 
     return false; 
    } 
    return true; 
} 

私は次の例外を取得:

Caused by: java.sql.SQLException: IJ031040: Connection is not associated with a managed connection: [email protected] 
    at org.jboss.jca.adapters.jdbc.WrappedConnection.lock(WrappedConnection.java:164) 
    at org.jboss.jca.adapters.jdbc.WrappedConnection.rollback(WrappedConnection.java:883) 

私はそれに対処する必要がありますどのように?

答えて

0

最初のjava.sql.SQLException: IJ031040は、インポート中の特定の結果と関連しているようです。その後、管理対象トランザクションのロールバックを禁止する別のjava.sql.SQLExceptionに置き換えられました。しかし、私は最終的にネイティブのSQL文を発行することによって、問題を解決することができます:

// Mark the current state as SAVEPOINT... 
Session session = this.em.unwrap(Session.class); 
session.doWork(new Work() { 
    @Override 
    public void execute(Connection connection) throws SQLException { 
     connection.prepareStatement("SAVEPOINT TRY_POSSIBILITY").executeUpdate(); 
    } 
}); 

// 
// Do all the risky changes... verify... decide... 
// 

// Rollback to SAVEPOINT if necessary! 
session.doWork(new Work() { 
    @Override 
    public void execute(Connection connection) throws SQLException { 
     connection.prepareStatement("ROLLBACK TO SAVEPOINT TRY_POSSIBILITY").executeUpdate(); 
    } 
}); 

は、これは、1つの大きな内の「ネストされたトランザクション」を可能にし、私の問題を解決しました。

関連する問題