0

I am using JavaEE7 and container managed transactions in my Project. Although i have @Transactional annotation on method, i am getting "Transaction must be running" exception. Code seems as following:

@Transactional(Transactional.TxType.MANDATORY)
public void myMethod(Project project) {

    final ObjectIdentity objectId = new ObjectIdentityImpl(project);
    final Sid sid = new PrincipalSid(SecurityContextHolder.getContext().getAuthentication());
    final Permission p = BasePermission.ADMINISTRATION;
    MutableAcl acl = null;
    try {
        List<Sid> sids = new ArrayList<>();
        sids.add(sid);
        acl = (MutableAcl) aclService.readAclById(objectId, sids);

    } catch (Exception ex) {
        acl = ((MutableAclService) aclService).createAcl(objectId); // This line causes exception
    }

    acl.insertAce(acl.getEntries().size(), p, sid, true);
    aclService.updateAcl(acl);
}

What is missing in this code, that transaction does not begin?

Kind regards,

Bilal

bilal
  • 103
  • 1
  • 1
  • 5
  • I think transaction begins but spring is not aware. There is a method to register transaction in TransactionSynchronizationManager.`TransactionSynchronizationManager.registerSynchronization(TransactionSynchronization synchronization)`. I think the transaction is not registered. – bilal Nov 25 '13 at 16:03

1 Answers1

4

A method annotated with Transactional.TxType.MANDATORY requires an already running transaction. It means that when the method invocation begins a transaction MUST be already started. You do that by starting transaction in another method that invokes your method annotated with Transactional.TxType.MANDATORY.

If you want to start a NEW transaction when there is no transaction currently running you must set the transaction type to Transactional.TxType.REQUIRED (new transaction will be started if no transaction is already runnig) or Transactional.TxType.REQUIRES_NEW (new transaction will be started no matter what) - it depends on your needs. The Transactional.TxType.REQUIRED type is the default transaction type in CDI so actually you can go with just @Transactional without specifying any type.

See http://docs.oracle.com/javaee/7/api/javax/transaction/Transactional.TxType.html for more information

Flying Dumpling
  • 1,294
  • 1
  • 11
  • 13