DBAppender and EJB managed transactions

Hi there, I think I found out, why I couldn't log in database as I described in December. I activated the status listener as mentioned in an earlier question concerning DBAppender like this: <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> and got this exception from JBoss: ERROR in ch.qos.logback.classic.db.DBAppender[myDBAppender] - problem appending event java.sql.SQLException: You cannot set autocommit during a managed transaction! at java.sql.SQLException: You cannot set autocommit during a managed transaction! at at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:878) at at org.jboss.jca.adapters.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:712) at at ch.qos.logback.core.db.DBAppenderBase.append(DBAppenderBase.java:90) at at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88) at at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:64) at at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:285) at at ch.qos.logback.classic.Logger.callAppenders(Logger.java:272) at at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:473) at at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:427) at at ch.qos.logback.classic.Logger.error(Logger.java:574) The transaction is handled by the EJB container and cannot be managed by DBAppenderBase line 90. I also tested the DBAppender in a web project that only uses Servlets and no EJBs. I could manage to log with the same log file. Is this a known issue? There has to be a possibility to log to DB without managing the transaction. Best if logback itself finds out, if managing transactions manually is allowed or not. Regards, Henning

I made a work around which is in fact working, but I'm not quite happy with it: I created a new Class DBAppender2 extending DBAppender and using the javax.transaction.UserTransaction where logback DBAppender used the transaction from the java.sql.Connection. I then created an EJB with BMT(bean managed transaction, see Annotation TransactionManagement). In this Bean I added some logging methods like debug(String msg) and so on. Those methods use Logger.debug and the like. I'm now injecting this EJB in my other EJBs, so I can log via 'LoggingEJB' which has its own transaction management. Some Code Snippets below: public class DBAppender2 extends DBAppender { private String jndiLocationTransactor; /* (non-Javadoc) * @see ch.qos.logback.core.db.DBAppenderBase#append(java.lang.Object) */ @Override public void append(ILoggingEvent eventObject) { Connection connection = null; try { connection = connectionSource.getConnection(); // connection.setAutoCommit(false); Context context = new InitialContext(); UserTransaction utx = (UserTransaction) context.lookup(jndiLocationTransactor); utx.begin(); // do something // connection.commit(); utx.commit(); } catch (Throwable sqle) { addError("problem appending event", sqle); } finally { DBHelper.closeConnection(connection); } } public String getJndiLocationTransactor() { return jndiLocationTransactor; } public void setJndiLocationTransactor(String jndiLocationTransactor) { this.jndiLocationTransactor = jndiLocationTransactor; } } config in logback.xml: <appender name="DBAppender2" class="ch.qos.logback.classic.db.DBAppender2"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ALL</level> </filter> <connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource"> <param name="jndiLocation" value="java:/jndiToConnection" /> </connectionSource> <jndiLocationTransactor>java:/jndiToUserTransaction</jndiLocationTransactor> </appender> Logging-EJB: @Stateless @TransactionManagement(TransactionManagementType.BEAN) public abstract class LoggingBean { private final Logger logger = LoggerFactory.getLogger(getClass()); public void debug(String msg) { logger.debug(msg); } } call from another EJB: @EJB LoggingBean loggerBean; loggerBean.debug("Test"); Hope this help others having the same problems. 2012/1/31 Henning Diederichs <grave1740@googlemail.com>:
Hi there,
I think I found out, why I couldn't log in database as I described in December. I activated the status listener as mentioned in an earlier question concerning DBAppender like this:
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
and got this exception from JBoss: ERROR in ch.qos.logback.classic.db.DBAppender[myDBAppender] - problem appending event java.sql.SQLException: You cannot set autocommit during a managed transaction! at java.sql.SQLException: You cannot set autocommit during a managed transaction! at at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:878) at at org.jboss.jca.adapters.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:712) at at ch.qos.logback.core.db.DBAppenderBase.append(DBAppenderBase.java:90) at at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88) at at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:64) at at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:285) at at ch.qos.logback.classic.Logger.callAppenders(Logger.java:272) at at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:473) at at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:427) at at ch.qos.logback.classic.Logger.error(Logger.java:574)
The transaction is handled by the EJB container and cannot be managed by DBAppenderBase line 90.
I also tested the DBAppender in a web project that only uses Servlets and no EJBs. I could manage to log with the same log file. Is this a known issue? There has to be a possibility to log to DB without managing the transaction. Best if logback itself finds out, if managing transactions manually is allowed or not.
Regards,
Henning
participants (1)
-
Henning Diederichs