[
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: [email protected]
For additional commands, e-mail: [email protected]