3

オブジェクトのリストがあります。それらはJPAの「場所」エンティティです。

List<Location> locations;

リストをループしてそれぞれを永続化するステートレス EJB があります。

public void createLocations() {
    List<Locations> locations = getListOfJPAManagedLocationEntities(); // I'm leaving out the details of this because it has nothing to do with the issue

    for(Location location : locations) {
        em.persist(location);
    }
}

コードは正常に動作します。問題はありません。ただし、問題は次のとおりです。これを全か無かのトランザクションにしたいのです。現在、for ループを通過するたびに、persist() メソッドは新しい行をデータベースに挿入します。100 個の位置オブジェクトがあり、54 番目のオブジェクトに問題があり、例外がスローされたとします。データベースには 53 のレコードが挿入されます。私が望むのは、それらのいずれかが成功する前に、それらすべてが成功する必要があるということです。

Java EE6、EJB 3.x、および JPA 2 の最新かつ最高のバージョンを使用しています。私の persistence.xml は JTA を使用しています。

<persistence-unit name="myPersistenceUnit" transaction-type="JTA">

そして、私はJTAを持っているのが好きです. JTA の使用をやめたくありません。90% の確率で、JTA は私がやりたいことを正確に実行します。しかし、この場合、私はそうではないようです。

EJB メソッドの開始と終了が JTA トランザクションの境界を示していると常に考えていたため、JTA についての私の理解は不正確であるに違いありません (上で示したように、実行中のメソッドは 1 つだけであると仮定します)。私の論理では、for ループが完了してメソッドが戻るまでトランザクションは終了せず、その時点でレコードは永続化されます。

SqlServer 2008 用の JTDS ドライバーを使用しています。おそらく、データベースはレコードをすぐにコミットせずにレコードを挿入したくないのでしょう。エンティティ ID は次のように定義されます。

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

仕様を確認しましたが、JTA 環境でさまざまな「UserTransaction」または「getTransaction()」メソッドを呼び出すことは適切ではありません。

それで、なにかお手伝いできますか?ありがとう。

4

3 に答える 3

0

JTAとコンテナ管理のトランザクションを使用する場合、セッションEJBメソッド呼び出しのデフォルトの動作はトランザクションで実行されます(これに注釈を付けるようなもの@TransactionAttribute(TransactionAttributeType.REQUIRED)です。つまり、コードはすでにトランザクションで実行され、期待どおりに実行されます。例外の場合行54で発生すると、以前に挿入されたすべての行がロールバックされます。ループのある時点で例外をスローすることで、先に進んでテストできます。メソッドによって宣言されたチェック済み例外をスローする場合は、コンテナは、その例外が発生したときに実行する必要があります。例外クラスに。で注釈を付ける必要があります@ApplicationException (rollback=true)

于 2013-02-20T21:42:53.307 に答える
0

JBossを使用しています。あなたのstandalone.xmlまたはdomain.xmlにデータソースを設定してください <datasource jta="true" ...>

于 2015-11-30T21:19:36.787 に答える
0

ループ中に重複したエントリがあった場合、ループは問題なく続行され、コンパイラがem.flush();ループ後にこの行に到達すると、例外がスローされ、トランザクションがロールバックされます。

于 2013-03-19T12:20:35.913 に答える