[ 
https://issues.apache.org/jira/browse/LOG4J2-438?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13827512#comment-13827512
 ] 

Dimitry Declercq commented on LOG4J2-438:
-----------------------------------------

I've added a few lines of code to JDBCDatabaseManager to fix this issue. This 
is a quickfix and is probably not good enough for use in the GA, especially 
since this doesn't cover the use-case when a buffer is used.

{code:title=JDBCDatabaseManager.java}
    @Override
    protected void writeInternal(final LogEvent event) {
            ...
            if (this.statement.executeUpdate() == 0) {
                throw new AppenderLoggingException("No records inserted in 
database table for log event in JDBC manager.");
            }
            // commit should only be called explicitly when autoCommit is 
disabled
            if (!this.connection.getAutoCommit()) {
                this.connection.commit();
            }
{code}

For the usecase with buffers the quickest way would be to add a commit hook in 
AbstractDatabaseManager which the JDBCDatabaseManager implements. I've not 
written this actual code (only in my head) and this should be consider a 
brainfart:
{code:title=AbstractDatabaseManager.java}
    public final synchronized void flush() {
        if (this.isConnected() && this.buffer.size() > 0) {
            for (final LogEvent event : this.buffer) {
                this.writeInternal(event);
            }
            this.commit();
            this.buffer.clear();
        }
    }

    protected void commit() {
        //Dummy implementation
    }
{code}

{code:title=JDBCDatabaseManager.java}
    protected void commit() {
        try {
            // commit should only be called explicitly when autoCommit is 
disabled
            if (!this.connection.getAutoCommit()) {
                this.connection.commit();
            }
        } catch (final SQLException e) {
            LOGGER.error("Could not send commit to database for [{}].", 
this.getName(), e);
        }
    }
{code}

> JDBCDatabaseManager does not send commit command
> ------------------------------------------------
>
>                 Key: LOG4J2-438
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-438
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Appenders
>    Affects Versions: 2.0-beta9
>         Environment: Java 7u45, Windows, H2
>            Reporter: Ralph Schaer
>            Assignee: Nick Williams
>            Priority: Minor
>
> I'm fiddling with the log4j jdbc appender and found an issue with datasources 
> that have the flag defaultAutoCommit set to false. With such datasources the 
> application has to call the method connection.commit() after an update 
> statement, if omitted nothing will be updated or inserted in the database.
> That is the problem with the class JDBCDatabaseManager. It executes the 
> statement (with this.statement.executeUpdate()) but does not call commit. 
> Nothing is inserted if the defaultAutoCommit flag of the datasource is set to 
> false. 
> One possible solution is to check the autoCommit flag of the datasource and 
> call commit when it's set to false.
> if (this.statement.executeUpdate() == 0) {
>   throw new AppenderLoggingException(
>    "No records inserted in database table for log event in JDBC manager.");
> }
>                       
> if (!this.connection.getAutoCommit()) {
>   this.connection.commit();
> }
> Maybe this has to be done differently when a buffer is used. The method 
> AbstractDatabaseManager.flush should only call commit after the loop. 
>         if (this.isConnected() && this.buffer.size() > 0) {
>             for (final LogEvent event : this.buffer) {
>                 this.writeInternal(event);
>             }
>            if (!connection.getAutoCommit()) {
>               connection.commit();
>            }
>             this.buffer.clear();
>         }
> Or maybe using the batch methods of jdbc would improve the performance even 
> more
> if (this.isConnected() && this.buffer.size() > 0) {
>   for (final LogEvent event : this.buffer) {
>     //create statement .......
>     statement.addBatch()
>   }
>   statement.executeBatch();
>   if (!connection.getAutoCommit()) {
>     connection.commit();
>   }
>   this.buffer.clear();
> }



--
This message was sent by Atlassian JIRA
(v6.1#6144)

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org

Reply via email to