You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ni...@apache.org on 2014/02/08 03:51:58 UTC
svn commit: r1565878 - in /logging/log4j/log4j2/trunk:
log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/
log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/
log4j-core/src/main/java/org/apache/logging/log4j/core/a...
Author: nickwilliams
Date: Sat Feb 8 02:51:58 2014
New Revision: 1565878
URL: http://svn.apache.org/r1565878
Log:
Part 2 of 2-part commit for fixing LOG4J2-407, LOG4J2-438, LOG4J2-442, LOG4J2-457, and LOG4J2-489: Changed database appenders to connect (borrow from pool) on every flush or every non-buffered writeInternal.
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManager.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPADatabaseManager.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLConnection.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManager.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLProvider.java
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppenderTest.java
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManagerTest.java
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManagerTest.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManager.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManager.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManager.java Sat Feb 8 02:51:58 2014
@@ -106,6 +106,13 @@ public abstract class AbstractDatabaseMa
}
/**
+ * Connects to the database and starts a transaction (if applicable). With buffering enabled, this is called when
+ * flushing the buffer begins, before the first call to {@link #writeInternal}. With buffering disabled, this is
+ * called immediately before every invocation of {@link #writeInternal}.
+ */
+ protected abstract void connectAndStart();
+
+ /**
* Performs the actual writing of the event in an implementation-specific way. This method is called immediately
* from {@link #write(LogEvent)} if buffering is off, or from {@link #flush()} if the buffer has reached its limit.
*
@@ -114,14 +121,24 @@ public abstract class AbstractDatabaseMa
protected abstract void writeInternal(LogEvent event);
/**
+ * Commits any active transaction (if applicable) and disconnects from the database (returns the connection to the
+ * connection pool). With buffering enabled, this is called when flushing the buffer completes, after the last call
+ * to {@link #writeInternal}. With buffering disabled, this is called immediately after every invocation of
+ * {@link #writeInternal}.
+ */
+ protected abstract void commitAndClose();
+
+ /**
* This method is called automatically when the buffer size reaches its maximum or at the beginning of a call to
* {@link #shutdown()}. It can also be called manually to flush events to the database.
*/
public final synchronized void flush() {
if (this.isRunning() && this.buffer.size() > 0) {
+ this.connectAndStart();
for (final LogEvent event : this.buffer) {
this.writeInternal(event);
}
+ this.commitAndClose();
this.buffer.clear();
}
}
@@ -138,7 +155,9 @@ public abstract class AbstractDatabaseMa
this.flush();
}
} else {
+ this.connectAndStart();
this.writeInternal(event);
+ this.commitAndClose();
}
}
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JDBCDatabaseManager.java Sat Feb 8 02:51:58 2014
@@ -53,17 +53,27 @@ public final class JDBCDatabaseManager e
}
@Override
- protected void startupInternal() throws SQLException {
- this.connection = this.connectionSource.getConnection();
- this.statement = this.connection.prepareStatement(this.sqlStatement);
+ protected void startupInternal() {
+ // nothing to see here
}
@Override
- protected void shutdownInternal() throws SQLException {
+ protected void shutdownInternal() {
+ if (this.connection != null || this.statement != null) {
+ this.commitAndClose();
+ }
+ }
+
+ @Override
+ protected void connectAndStart() {
try {
- Closer.close(this.statement);
- } finally {
- Closer.close(this.connection);
+ this.connection = this.connectionSource.getConnection();
+ this.connection.setAutoCommit(false);
+ this.statement = this.connection.prepareStatement(this.sqlStatement);
+ } catch (SQLException e) {
+ throw new AppenderLoggingException(
+ "Cannot write logging event or flush buffer; JDBC manager cannot connect to the database.", e
+ );
}
}
@@ -71,7 +81,8 @@ public final class JDBCDatabaseManager e
protected void writeInternal(final LogEvent event) {
StringReader reader = null;
try {
- if (!this.isRunning() || this.connection == null || this.connection.isClosed()) {
+ if (!this.isRunning() || this.connection == null || this.connection.isClosed() || this.statement == null
+ || this.statement.isClosed()) {
throw new AppenderLoggingException(
"Cannot write logging event; JDBC manager not connected to the database.");
}
@@ -110,6 +121,37 @@ public final class JDBCDatabaseManager e
}
}
+ @Override
+ protected void commitAndClose() {
+ try {
+ if (this.connection != null && !this.connection.isClosed()) {
+ this.connection.commit();
+ }
+ } catch (SQLException e) {
+ throw new AppenderLoggingException("Failed to commit transaction logging event or flushing buffer.", e);
+ } finally {
+ try {
+ if (this.statement != null) {
+ this.statement.close();
+ }
+ } catch (Exception e) {
+ LOGGER.warn("Failed to close SQL statement logging event or flushing buffer.", e);
+ } finally {
+ this.statement = null;
+ }
+
+ try {
+ if (this.connection != null) {
+ this.connection.close();
+ }
+ } catch (Exception e) {
+ LOGGER.warn("Failed to close database connection logging event or flushing buffer.", e);
+ } finally {
+ this.connection = null;
+ }
+ }
+ }
+
/**
* Creates a JDBC manager for use within the {@link JDBCAppender}, or returns a suitable one if it already exists.
*
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPADatabaseManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPADatabaseManager.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPADatabaseManager.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/JPADatabaseManager.java Sat Feb 8 02:51:58 2014
@@ -39,6 +39,9 @@ public final class JPADatabaseManager ex
private EntityManagerFactory entityManagerFactory;
+ private EntityManager entityManager;
+ private EntityTransaction transaction;
+
private JPADatabaseManager(final String name, final int bufferSize,
final Class<? extends AbstractLogEventWrapperEntity> entityClass,
final Constructor<? extends AbstractLogEventWrapperEntity> entityConstructor,
@@ -56,14 +59,31 @@ public final class JPADatabaseManager ex
@Override
protected void shutdownInternal() {
+ if (this.entityManager != null || this.transaction != null) {
+ this.commitAndClose();
+ }
if (this.entityManagerFactory != null && this.entityManagerFactory.isOpen()) {
this.entityManagerFactory.close();
}
}
@Override
+ protected void connectAndStart() {
+ try {
+ this.entityManager = this.entityManagerFactory.createEntityManager();
+ this.transaction = this.entityManager.getTransaction();
+ this.transaction.begin();
+ } catch (Exception e) {
+ throw new AppenderLoggingException(
+ "Cannot write logging event or flush buffer; manager cannot create EntityManager or transaction.", e
+ );
+ }
+ }
+
+ @Override
protected void writeInternal(final LogEvent event) {
- if (!this.isRunning() || this.entityManagerFactory == null) {
+ if (!this.isRunning() || this.entityManagerFactory == null || this.entityManager == null
+ || this.transaction == null) {
throw new AppenderLoggingException(
"Cannot write logging event; JPA manager not connected to the database.");
}
@@ -75,23 +95,38 @@ public final class JPADatabaseManager ex
throw new AppenderLoggingException("Failed to instantiate entity class [" + this.entityClassName + "].", e);
}
- EntityManager entityManager = null;
- EntityTransaction transaction = null;
try {
- entityManager = this.entityManagerFactory.createEntityManager();
- transaction = entityManager.getTransaction();
- transaction.begin();
- entityManager.persist(entity);
- transaction.commit();
+ this.entityManager.persist(entity);
} catch (final Exception e) {
- if (transaction != null && transaction.isActive()) {
- transaction.rollback();
+ if (this.transaction != null && this.transaction.isActive()) {
+ this.transaction.rollback();
+ this.transaction = null;
}
- throw new AppenderLoggingException("Failed to insert record for log event in JDBC manager: " +
+ throw new AppenderLoggingException("Failed to insert record for log event in JPA manager: " +
e.getMessage(), e);
+ }
+ }
+
+ @Override
+ protected void commitAndClose() {
+ try {
+ if (this.transaction != null && this.transaction.isActive()) {
+ this.transaction.commit();
+ }
+ } catch (Exception e) {
+ if (this.transaction != null && this.transaction.isActive()) {
+ this.transaction.rollback();
+ }
} finally {
- if (entityManager != null && entityManager.isOpen()) {
- entityManager.close();
+ this.transaction = null;
+ try {
+ if (this.entityManager != null && this.entityManager.isOpen()) {
+ this.entityManager.close();
+ }
+ } catch (Exception e) {
+ LOGGER.warn("Failed to close entity manager while logging event or flushing buffer.", e);
+ } finally {
+ this.entityManager = null;
}
}
}
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLConnection.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLConnection.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLConnection.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLConnection.java Sat Feb 8 02:51:58 2014
@@ -55,7 +55,11 @@ public interface NoSQLConnection<W, T ex
/**
* Closes the underlying connection. This method call should be idempotent. Only the first call should have any
* effect; all further calls should be ignored. It's possible the underlying connection is stateless (such as an
- * HTTP web service), in which case this method would be a no-op.
+ * HTTP web service), in which case this method would be a no-op. This method should also commit any open
+ * transactions, if applicable and if not already committed.<br />
+ * <br />
+ * If this connection is part of a connection pool, executing this method should commit the transaction and return
+ * the connection to the pool, but it should not actually close the underlying connection.
*/
@Override
void close();
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManager.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManager.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManager.java Sat Feb 8 02:51:58 2014
@@ -45,13 +45,22 @@ public final class NoSQLDatabaseManager<
@Override
protected void startupInternal() {
- this.connection = this.provider.getConnection();
+ // nothing to see here
}
@Override
protected void shutdownInternal() {
- if (this.connection != null && !this.connection.isClosed()) {
- this.connection.close();
+ if (this.connection != null) {
+ this.commitAndClose();
+ }
+ }
+
+ @Override
+ protected void connectAndStart() {
+ try {
+ this.connection = this.provider.getConnection();
+ } catch (Exception e) {
+ throw new AppenderLoggingException("Failed to get connection from NoSQL connection provider.", e);
}
}
@@ -139,6 +148,17 @@ public final class NoSQLDatabaseManager<
this.connection.insertObject(entity);
}
+ @Override
+ protected void commitAndClose() {
+ try {
+ if (this.connection != null && !this.connection.isClosed()) {
+ this.connection.close();
+ }
+ } catch (Exception e) {
+ throw new AppenderLoggingException("Failed to commit and close NoSQL connection in manager.", e);
+ }
+ }
+
private NoSQLObject<W>[] convertStackTrace(final StackTraceElement[] stackTrace) {
final NoSQLObject<W>[] stackTraceEntities = this.connection.createList(stackTrace.length);
for (int i = 0; i < stackTrace.length; i++) {
Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLProvider.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLProvider.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLProvider.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLProvider.java Sat Feb 8 02:51:58 2014
@@ -26,7 +26,10 @@ public interface NoSQLProvider<C extends
/**
* Obtains a connection from this provider. The concept of a connection in this case is not strictly an active
* duplex UDP or TCP connection to the underlying database. It can be thought of more as a gateway, a path for
- * inserting objects that may use a persistent connection or may use HTTP web service calls, etc.
+ * inserting objects that may use a persistent connection or may use HTTP web service calls, etc.<br />
+ * <br />
+ * Where applicable, this method should return a connection from the connection pool as opposed to opening a
+ * brand new connection every time.
*
* @return a connection that can be used to create and persist objects to this database.
* @see NoSQLConnection
Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppenderTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppenderTest.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppenderTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppenderTest.java Sat Feb 8 02:51:58 2014
@@ -126,16 +126,24 @@ public class AbstractDatabaseAppenderTes
final LogEvent event1 = createStrictMock(LogEvent.class);
final LogEvent event2 = createStrictMock(LogEvent.class);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event1));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
replay(this.manager, this.appender);
this.appender.append(event1);
verify(this.manager, this.appender);
reset(this.manager, this.appender);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event2));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
replay(this.manager, this.appender);
this.appender.append(event2);
Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManagerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManagerTest.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManagerTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseManagerTest.java Sat Feb 8 02:51:58 2014
@@ -123,26 +123,42 @@ public class AbstractDatabaseManagerTest
this.manager.startupInternal();
expectLastCall();
- this.manager.writeInternal(same(event1));
- expectLastCall();
replay(this.manager);
this.manager.startup();
+ verify(this.manager);
+ reset(this.manager);
+ this.manager.connectAndStart();
+ expectLastCall();
+ this.manager.writeInternal(same(event1));
+ expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
+ replay(this.manager);
+
this.manager.write(event1);
verify(this.manager);
reset(this.manager);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event2));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
replay(this.manager);
this.manager.write(event2);
verify(this.manager);
reset(this.manager);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event3));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
replay(this.manager);
this.manager.write(event3);
@@ -169,6 +185,8 @@ public class AbstractDatabaseManagerTest
verify(this.manager);
reset(this.manager);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event1));
expectLastCall();
this.manager.writeInternal(same(event2));
@@ -177,6 +195,8 @@ public class AbstractDatabaseManagerTest
expectLastCall();
this.manager.writeInternal(same(event4));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
replay(this.manager);
this.manager.write(event4);
@@ -202,12 +222,16 @@ public class AbstractDatabaseManagerTest
verify(this.manager);
reset(this.manager);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event1));
expectLastCall();
this.manager.writeInternal(same(event2));
expectLastCall();
this.manager.writeInternal(same(event3));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
replay(this.manager);
this.manager.flush();
@@ -233,12 +257,16 @@ public class AbstractDatabaseManagerTest
verify(this.manager);
reset(this.manager);
+ this.manager.connectAndStart();
+ expectLastCall();
this.manager.writeInternal(same(event1));
expectLastCall();
this.manager.writeInternal(same(event2));
expectLastCall();
this.manager.writeInternal(same(event3));
expectLastCall();
+ this.manager.commitAndClose();
+ expectLastCall();
this.manager.shutdownInternal();
expectLastCall();
replay(this.manager);
Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManagerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManagerTest.java?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManagerTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/nosql/NoSQLDatabaseManagerTest.java Sat Feb 8 02:51:58 2014
@@ -69,7 +69,7 @@ public class NoSQLDatabaseManagerTest {
expect(this.provider.getConnection()).andReturn(this.connection);
replay(this.provider, this.connection);
- manager.startupInternal();
+ manager.connectAndStart();
verify(this.provider, this.connection);
reset(this.provider, this.connection);
@@ -78,7 +78,7 @@ public class NoSQLDatabaseManagerTest {
expectLastCall();
replay(this.provider, this.connection);
- manager.shutdownInternal();
+ manager.commitAndClose();
} finally {
try {
manager.release();
@@ -120,16 +120,22 @@ public class NoSQLDatabaseManagerTest {
@Test
public void testWriteInternalNotConnected02() {
- expect(this.provider.getConnection()).andReturn(this.connection);
- replay(this.provider, this.connection);
-
final NoSQLDatabaseManager<?> manager = NoSQLDatabaseManager.getNoSQLDatabaseManager("name", 0, this.provider);
try {
+ replay(this.provider, this.connection);
+
manager.startup();
verify(this.provider, this.connection);
reset(this.provider, this.connection);
+ expect(this.provider.getConnection()).andReturn(this.connection);
+ replay(this.provider, this.connection);
+
+ manager.connectAndStart();
+
+ verify(this.provider, this.connection);
+ reset(this.provider, this.connection);
final LogEvent event = createStrictMock(LogEvent.class);
expect(this.connection.isClosed()).andReturn(true);
@@ -159,16 +165,22 @@ public class NoSQLDatabaseManagerTest {
@Test
public void testWriteInternal01() {
- expect(this.provider.getConnection()).andReturn(this.connection);
- replay(this.provider, this.connection);
-
final NoSQLDatabaseManager<?> manager = NoSQLDatabaseManager.getNoSQLDatabaseManager("name", 0, this.provider);
try {
+ replay(this.provider, this.connection);
+
manager.startup();
verify(this.provider, this.connection);
reset(this.provider, this.connection);
+ expect(this.provider.getConnection()).andReturn(this.connection);
+ replay(this.provider, this.connection);
+
+ manager.connectAndStart();
+
+ verify(this.provider, this.connection);
+ reset(this.provider, this.connection);
final Capture<NoSQLObject<Map<String, Object>>> capture = new Capture<NoSQLObject<Map<String, Object>>>();
@@ -245,16 +257,22 @@ public class NoSQLDatabaseManagerTest {
@Test
public void testWriteInternal02() {
- expect(this.provider.getConnection()).andReturn(this.connection);
- replay(this.provider, this.connection);
-
final NoSQLDatabaseManager<?> manager = NoSQLDatabaseManager.getNoSQLDatabaseManager("name", 0, this.provider);
try {
+ replay(this.provider, this.connection);
+
manager.startup();
verify(this.provider, this.connection);
reset(this.provider, this.connection);
+ expect(this.provider.getConnection()).andReturn(this.connection);
+ replay(this.provider, this.connection);
+
+ manager.connectAndStart();
+
+ verify(this.provider, this.connection);
+ reset(this.provider, this.connection);
final Capture<NoSQLObject<Map<String, Object>>> capture = new Capture<NoSQLObject<Map<String, Object>>>();
@@ -379,16 +397,22 @@ public class NoSQLDatabaseManagerTest {
@Test
public void testWriteInternal03() {
- expect(this.provider.getConnection()).andReturn(this.connection);
- replay(this.provider, this.connection);
-
final NoSQLDatabaseManager<?> manager = NoSQLDatabaseManager.getNoSQLDatabaseManager("name", 0, this.provider);
try {
+ replay(this.provider, this.connection);
+
manager.startup();
verify(this.provider, this.connection);
reset(this.provider, this.connection);
+ expect(this.provider.getConnection()).andReturn(this.connection);
+ replay(this.provider, this.connection);
+
+ manager.connectAndStart();
+
+ verify(this.provider, this.connection);
+ reset(this.provider, this.connection);
final Capture<NoSQLObject<Map<String, Object>>> capture = new Capture<NoSQLObject<Map<String, Object>>>();
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1565878&r1=1565877&r2=1565878&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Sat Feb 8 02:51:58 2014
@@ -21,6 +21,25 @@
</properties>
<body>
<release version="2.0-RC1" date="2014-MM-DD" description="Bug fixes and enhancements">
+ <action issue="LOG4J2-489" dev="nickwilliams" type="fix">
+ Fixed the JPAAppender's overuse of transactions by connecting (borrowing from pool) on new write internal or on
+ flush.
+ </action>
+ <action issue="LOG4J2-457" dev="nickwilliams" type="fix">
+ Fixed failure of JDBC and JPA appender to properly release database connections by connecting (borrowing from
+ pool) on new write internal or on flush.
+ </action>
+ <action issue="LOG4J2-442" dev="nickwilliams" type="fix">
+ Fixed problem with JDBC and JPA appender connectivity in WebSphere by connecting (borrowing from pool) on new
+ write internal or on flush.
+ </action>
+ <action issue="LOG4J2-438" dev="nickwilliams" type="fix">
+ Ensured the JDBCAppender commits transactions after a single write or a flush of multiple writes.
+ </action>
+ <action issue="LOG4J2-407" dev="nickwilliams" type="fix">
+ Fixed inability to recover from lost database connection in database appenders by connecting (borrowing from
+ pool) on new write internal or on flush.
+ </action>
<action dev="nickwilliams" type="delete">
Removed the DataSourceConnectionSource and the <DriverManager> plugin for the JDBC Appender. It is not
safe to use. Please use the DataSource or factory connection sources backed by a connection pool.