2015-11-17 3 views
7

をロックしているようだ:EJB @AsynchronousはJSFの行を挿入し、リアルタイムに取得するスレッドが、私は次のことを達成しようとしています

@ManagedBean 
@RequestScoped 
public class SomeManagedBean{ 

    // Entity Manager injection 
    private EntityManager _entity_manager; 

    @EJB 
    private SomeSingletonRemote _singleton; 

    public void createScenario(){ 
     _singleton.createScenario(); 
    } 

    public List<Event> getEventList(){ 
     // Retrieve events from database 
    } 
} 
豆管理

EJB3シングルトン

@Singleton 
@Startup 
public class SomeSingleton implements SomeSingletonLocal { 

    // Entity Manager injection 
    private EntityManager _entity_manager; 

    @Override 
    @Asynchronous 
    public void createScenario(){ 
     method1(); 
     method2(); 
     // ... 
    } 

    public void method1(){ 
     // Persist an Event in a Database. 
    } 

    public void method2(){ 
     // Persist an Event in a Database. 
    } 

} 

JSFビュー

<h:form> 
    <p:commandButton value="Start Long Stuff" 
     actionListener="#{SomeManagedBean.createScenario}" /> 
    <h:outputText id="count" value="#{SomeManagedBean.getEventList.size()}" /> 
      <p:poll interval="1" update="count" /> 
</h:form> 

ログ

- > SomeManagedBean.getEventList()
< -SomeManagedBean.getEventList()//サイズ= 0

//ブトンをクリック
- > SomeManagedBean .createScenario()
            - > SomeSingleton.createScenario()
< -SomeManagedBean.createScenario()

- > SomeManagedBean.getEventList()// SomeSingleton.createScenario
の終わりで終了します - > SomeSingleton.method1()
を持続//
< -SomeSingleton.method1()...
- > SomeSingleton.methodN()
< -SomeSingleton.methodN()//持続

< -SomeSingleton.createScenario()

< -SomeManagedBean.getEventList()//サイズ= N

私は2つのmethodI()呼び出し(すなわち、間getEventListに少なくとも一つの呼び出しを期待。毎秒)。 SomeSingleton.createScenario()に入ると、なぜgetEventListが一時停止しているのかわかりません。

エンティティマネージャまたはcreateScenario内のトランザクションにロックがあるようです。それは再入国の問題ですか?

答えて

8

@Singletonは、実際にはデフォルトで読み取り/書き込みロックされています。これはトランザクションと厳密には関係なく、並行性に関連しています。 a.oを参照してください。 Java EE 7 tutorial on the subject

解決する方法の1つは、@ConcurrencyManagementBEANに設定することです。この方法では、基本的にコンテナに並行性を気にせず、すべての責任を自分で負うように指示します。

@Singleton 
@ConcurrencyManagement(ConcurrencyManagementType.BEAN) 
public class SomeSingleton {} 

もう一つの方法は、彼らは同時に呼び出すことができるように明示的にクラスまたは読み取り専用の方法でREAD@Lockを設定することです。@Lock(LockType.WRITE)の明示的なメソッドが同じインスタンスで呼び出された場合にのみ、ロックが発生します。

@Singleton 
@Lock(LockType.READ) 
public class SomeSingleton {} 
+0

なぜ彼ら[言及](https://docs.oracle.com/javaee/7/tutorial/ejb-basicexamples002.htm)、「*何が 'Lock' @注釈がシングルトン上に存在しない場合クラス、デフォルトのロックタイプ、 '@Lock(LockType.WRITE)'は、すべてのビジネスメソッドとタイムアウトメソッド*に適用されますか? – Tiny

+0

@Tiny:どの部分があなたにはっきりしていないかを明確にしてください。基本的に、クラスに '@ Lock'アノテーションがない場合、すべてのメソッドはデフォルトで' @Lock(LockType.WRITE) 'になります。これは答えによってもカバーされます(しかし、おそらく少し不明な点があり、あなたのフィードバックに応じてその部分を改善したいと思います)。 – BalusC

+0

これらの太字はここにあります: "* A' @ Singleton'は実際にはデフォルトで**読み書きロックされています*** "。 (申し訳ありませんが、最初は間違った印象を受けていました。シングルトンのEJBはデフォルトで「読み取り」と「書き込み」の両方のロックを持っています。このように、状態を変更するメソッドはデフォルトで「書き込み」され、変更状態はデフォルトで "読み取り"ロックされていなければなりません)。 – Tiny

関連する問題