Java EE @TransactionManagement.BEAN - how does it combine with container managed beans?

落花浮王杯 提交于 2021-02-08 04:01:27

问题


How will the transaction started in callSessionBean2() behave in the following scenario? Is it suspended? What happens if an exception is thrown in SessionBean2? SessionBean2 was setup with BEAN transaction management type because it does not communicate with any database, only with AD server via LDAP.

I'm asking because I've been having issues in a production server some week after deployment that calls to SessionBean2 starts to hang, with transaction timeouts as the only error. I figured this setup might be a bad thing, can anyone shed light on this?

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class SessionBean1 {
    @Inject private SessionBean2 sessionBean2;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void callSessionBean2(){
        sessionBean2.doThingsThatMightCauseException();
    }
}

@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class SessionBean2 {
    public void doThingsThatMightCauseException(){...}
}

回答1:


As declared in EJB 3.1 spec (§13.6.1), the caller's transaction will be suspended:

If the client request is associated with a transaction T1, and the instance is not associated with a transaction, the container suspends the client’s transaction association and invokes the method with an unspecified transaction context. The container resumes the client’s transaction association (T1) when the method (together with any associated interceptor methods) completes.

So the transaction associated with SessionBean1 gets suspended, and the exceptions thrown by SessionBean2 in either case will be handled by the calling bean, with the appropriate semantics (i.e. treated by the CMT session)

Your code is correct, though I'd rather use:

@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class SessionBean2 {
    public void doThingsThatMightCauseException(){...}
}

to the same effect.

The problem you are experiencing may be related to the @Singleton annotation, which according to §4.8.5.3 and §4.8.5.3 defaults the bean to be:

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Lock(LockType.WRITE)

This serializes the invocations of doThingsThatMightCauseException, causing random ConcurrentAccessTimeoutException. Although the concurrent access timeout is configurable through @AccessTimeout, it will lead to a transaction timeout if the (serialized) doThingsThatMightCauseException access delay exceeds the timeout defined for CMT transactions (remember, the CMT transaction associated with SessionBean1 gets suspended, but the clock is still counting...).

Wrapping it up:

You need (with proper care to shared state) to change the access lock on doThingsThatMightCauseException with:

@Lock(LockType.READ)
public void doThingsThatMightCauseException(){...}

This will remove the access serialization, hopefully solving your timeout problems.

If you still experience timeouts, it will be related to the slowness of the operations included in doThingsThatMightCauseException. In this case you'll need to either:

  • call the method outside of any transaction,
  • or change the CMT transaction timeout (in the AS specific configuration/deployment)
  • or convert SessionBean1 to BMT, thus leveraging UserTransaction.setTransactionTimeout



回答2:


My advise is to manage all transaction manually. According to Java 6 EE specification:

Enterprise beans that use container-managed transaction demarcation must not use any transaction-management methods that interfere with the container’s transaction demarcation boundaries. Examples of such methods are the commit, setAutoCommit, and rollback methods of java.sql.Connection or the commit and rollback methods of javax.jms.Session. If you require control over the transaction demarcation, you must use application-managed transaction demarcation.

Enterprise beans that use container-managed transaction demarcation also must not use the javax.transaction.UserTransaction interface.



来源:https://stackoverflow.com/questions/14154142/java-ee-transactionmanagement-bean-how-does-it-combine-with-container-managed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!