Search code examples
jpawebspherejtawebsphere-liberty

@TransactionAttribute(REQUIRED) cause no effect


On the Oracle Database, Entity Table has constraint check(ID < 90). So, the second persist method throws SQLException.

But both code snippets below work equally: first persist method doesn't commit even without JTA Annotations. Why both variants works the same way?

@Stateless
public class EntityServiceImpl implements EntityService{

@PersistenceContext
private EntityManager enManager;
@Resource
private SessionContext sessionCtx; 

@TransactionAttribute(REQUIRED)
public void updateEntity(List<Entity> entity) {
    try {
        Entity validEntity = entity.get(10);
        enManager.persist(validEntity);
        Entity inValidEntity = entity.get(90);
        enManager.persist(inValidEntity);

    } catch(Exception ex) {
        sessionCtx.setRollbackOnly();
        throw ex;
    }
}

second snippet:

public void updateEntity(List<Entity> entity) {
        Entity validEntity = entity.get(10);
        enManager.persist(validEntity);
        Entity inValidEntity = entity.get(90);
        enManager.persist(inValidEntity);
}

persistence.xml

<persistence-unit name="WASLiberty" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="eclipselink.logging.level.sql" value="FINEST"/>
        <property name="eclipselink.logging.parameters" value="true"/>      
    </properties>
</persistence-unit>

EDIT:

From Oracle:

Required Attribute If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.

The Required attribute is the implicit transaction attribute for all enterprise bean methods running with container-managed transaction demarcation. You typically do not set the Required attribute unless you need to override another transaction attribute. Because transaction attributes are declarative, you can easily change them later

Does it means that there is no need to declare @TransactionAttribute(REQUIRED) unless we need another TransactionAttributeType except "REQUIRED"?


Solution

  • Yes, your understanding that @TransactionAttribute(REQUIRED) is the default behavior is correct.

    For session beans and MDBs this annotation is implied by default, specifying the annotation as you did in the first snippet is just being verbose. So the only time you would really need to specify a @TransactionAttribute is if you are using something other than REQUIRED for the value.