[logback-user] DBAppender and EJB managed transactions

Henning Diederichs grave1740 at googlemail.com
Fri Feb 3 16:12:01 CET 2012


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 at 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


More information about the Logback-user mailing list