There is the following code snippet inside a servlet
@PeristenceContext
private EntityManager entityManager;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException,
IOException {
runTransaction();
}
@Transactional
public void runTransaction() {
entityManager.merge(entityA);
entityManager.remove(entityC);
}
entityManager methods are invoked inside container-managed transaction bounday => Question: is there any problem when calling the runTransaction() inside the doPost method? esp. is calling of runTransaction() thread-safe? If this approach is problematic, how to resolve?
In your case, it may be thread-safe (cause it is request dependent), but it certainly is not transactional.
@Transactionalannotation activates transactions boundaries only when there is a "business method invocation" as defined by item 2.6.2 of CDI spec. In your case, servlet's doPost is calling a method inside its own class, so it will not be intercepted.To be able to start the transaction, you should move the database code (entitymanager injection and runTransaction method) to another CDI bean (you may choose a
@RequestScopedto be thread-safe) and call that bean from your servlet. So:As
dataManageris a@RequestScopedCDI proxy, each time a call is made to it, the proper request context bean will be called, making it request dependent and thread-safe. Note that data sharing between beans may interfere the thread-safiness of the execution, so choose what you pass torunTransactionmethod wisely.