我需要审计ejb bean的调用。所谓审计是指将当前登录用户、方法名称和其他详细信息写入数据库。我决定使用CDI装饰器来完成:
@Decorator
public class AccountServiceBeanDecorator implements AccountService {
@Inject
@Delegate
@Any
AccountService accountService;
@EJB
private AuditService auditService;
@Override
public Account createAccount(Account account) {
auditService.saveAudit("Method: createAccount", currentUser, "Creating account by admin");
return accountService.createAccount(account);
}
}
以及装饰类:
@Stateless
public class AccountServiceBean implements AccountService {
@Override
public Account createAccount(Account account) {
...
}
}
现在,如果我从另一个EJB无状态bean调用AccountService,事务会发生什么?
@Stateless
public ApplicationFacadeBean implements ApplicationFacade {
@EJB
private AccountService accountService;
@Override
public Account createAccount(Account account) {
return accountService.createAccount(account);
}
}
我希望在装饰器(AccountServiceBeanDecorator)和被装饰类(AccountServiceBean)中记录事务状态,因此我在这两个类中注入了TransactionSynchronizationRegistry作为资源:
@Decorator
public class AccountServiceBeanDecorator implements AccountService {
@Inject
@Delegate
@Any
AccountService accountService;
@EJB
private AuditService auditService;
@Resource
private TransactionSynchronizationRegistry reg;
@Override
public Account createAccount(Account account) {
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
log.info("tx ({}): {}", new Object[] {reg.getTransactionStatus(), reg.getTransactionKey()});
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
auditService.saveAudit("Method: createAccount", currentUser, "Creating account by admin");
return accountService.createAccount(account);
}
}
并且
@Stateless
public class AccountServiceBean implements AccountService {
@Resource
private TransactionSynchronizationRegistry reg;
@Override
public Account createAccount(Account account) {
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
log.info("tx ({}): {}", new Object[] {reg.getTransactionStatus(), reg.getTransactionKey()});
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
...
}
}
我收到了奇怪的行为:
log from decorator
tx (0): JavaEETransactionImpl: txId=6 nonXAResource=null jtsTx=null localTxStatus=0 syncs=[com.sun.ejb.containers.ContainerSynchronization@68fb15d0]]]
NullPointerException on second log (reg is null).
有人能给我解释一下吗?AccountServiceBean类是否在与ApplicationFacade相同的事务中被调用?
谢谢