2011-12-08 12 views
4

BMT内で(UserTransactionを使用)、別のステートレスEJBのメソッドを呼び出します。このトランザクションをロールバックすると、EJBメソッドで作成されたエンティティはロールバックされません。 JPA 2.0でEJB 3.1を使用します。トランザクションは、メソッドdoTheTransaction()で始まる:ステートレスBeanへの呼び出しでJPAトランザクションのロールバックが失敗する

@Stateless 
@LocalBean 
@TransactionManagement(TransactionManagementType.BEAN) 
public class TaskExecutor { 

    @Inject private SomeEntityFacade someEntityEJB; 
    @Inject private RandomEJB randomEJB; 
    @Resource private UserTransaction ut; 

    @Asynchronous 
    public Future<String> doTheTransaction() { // we start here 

     try { 
      SomeEntity someEntity = new SomeEntity(); 
      someEntityEJB.create(someEntity); // this entity is rolled back 

      // call another EJB to create a SomeEntity, this entity is not rolled back 
      randomEJB.createSomeEntity(); 

      // cause error for test 
      int i = 5/0; 

      ut.commit(); 
     } catch (java.lang.ArithmeticException e) { 
      ut.rollback(); 
     } 
    } 
    // Omitted exceptions thrown by UserTransaction methods because they give no problems 
} 

RandomEJB:

@Stateless 
@LocalBean 
@TransactionManagement(TransactionManagementType.BEAN) 
public class RandomEJB { 

    @Inject private SomeEntityFacade someEntityEJB; 

    public void createSomeEntity() { 
     // same code to create entity as in TaskExecutor: 
     SomeEntity someEntity = new SomeEntity(); 
     someEntityEJB.create(someEntity); 
    } 
} 

ここでは、完全なものにするにSomeEntityの重要な部分です:

@Stateless 
@LocalBean 
public class SomeEntityFacade { 

    @PersistenceContext(unitName = "com.mysite.PU") 
    private EntityManager em; 

    public void create (SomeEntity p_someEntity) { 
     em.persist(p_someEntity); 
    } 

あなたが興味を持っている場合、これは私のpersistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="com.mysite.PU" transaction-type="JTA"> 
    <jta-data-source>jdbc/myDatabase</jta-data-source> 
    <properties></properties> 
    </persistence-unit> 
</persistence> 

RandomEJBで作成されたエンティティがロールバックされないのはなぜですか?トランザクション内で直接作成されたエンティティは?

多分this postが関連していますが、私は本当に答えを理解していません。

編集:エラーが見つかりました:@TransactionManagement(TransactionManagementType.BEAN)RandomEJBに注釈を付けます。私の理解では、BMTトランザクションは他のBMT注釈付きメソッドを通じて伝播されず、新しいトランザクションが作成されます。最初のトランザクションが失敗してロールバックすることができる間、そのトランザクションは成功することができます。私はBMT/CMT注釈付きメソッドを使用するときは注意する必要があると思います。誰かがこれを確認できますか?

+0

"私の理解では、BMTトランザクションは他のBMT注釈付きメソッドで伝播されず、代わりに新しいトランザクションが作成されます。"いいえ! BMTであるため、明示的に作成しない限り、作成されません。それは、トランザクションなしで実行されると言うのがより理にかなっています。 –

答えて

3

BMT beanはお互いにトランザクションを共有していません。

これは、別のBMTで明示的に開始した取引を再利用できないことを意味します。 BMTは、「ゲームの内容を知っているので、自分でトランザクションのものを管理します」のようなものです。

だから:

  • BMT - > BMTは
  • BMTをトランザクションを共有することはありません - それはコンテナの場合、それは気にしない - > CMTは(CMTは、実際のトランザクションを使用しますシェア取引意志開始された、またはユーザーが開始した - トランザクションが存在するということだけに興味があります)。
関連する問題