--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.sql.tests</groupId>
+ <artifactId>sql-tests</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>sql-tests</name>
+ <url>http://gumartinm.name</url>
+ <description>SQL Tests</description>
+ <organization>
+ <name>Gustavo Martin Morcuende</name>
+ <url>http://www.gumartinm.name</url>
+ </organization>
+ <scm>
+ <developerConnection>scm:git:http://git.gumartinm.name/SQLTest</developerConnection>
+ <url>http://git.gumartinm.name/SQLTest</url>
+ </scm>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <spring.version>4.0.5.RELEASE</spring.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <!--
+ ********************************************************************
+ SLF4J AND LOG4J 2. See: http://logging.apache.org/log4j/2.x/
+ ********************************************************************
+ -->
+ <!--
+ 1/2 Required dependency for log4j 2 with slf4j: binding
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.0-rc1</version>
+ </dependency>
+ <!--
+ 2/2 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.0-rc1</version>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>2.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.mchange</groupId>
+ <artifactId>c3p0</artifactId>
+ <version>0.9.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <!-- I just have the source code for this version -->
+ <version>5.1.6</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ <compilerArgument>-Xlint:deprecation</compilerArgument>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Specification-Title>${project.description}</Specification-Title>
+ <Specification-Version>${project.version}</Specification-Version>
+ <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+ <Implementation-Title>${project.description}</Implementation-Title>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package de.sql.tests;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RawJDBCExample {
+ private static final Logger logger = LoggerFactory.getLogger(RawJDBCExample.class);
+ private static final String DB_URL =
+ "jdbc:mysql://127.0.0.1:3306/n2a?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";
+
+ public static void main(final String[] args) {
+ Connection connection = null;
+ Statement statement = null;
+ ResultSet answer = null;
+ PreparedStatement preparedStatement = null;
+ try {
+ // 1. Register JDBC driver
+ //
+ // Register JDBC driver (by itself) with the DriverManager!!!
+ // (see static initializers in com.mysql.jdbc.Driver)
+ //
+ // otherwise, you could do it like this:
+ // DriverManager.registerDriver(new Driver()); (it should be the same)
+ //
+ Class.forName("com.mysql.jdbc.Driver");
+
+ // 2. Open a connection
+ logger.info("Connecting to database");
+ connection = DriverManager.getConnection(RawJDBCExample.DB_URL, "root", "");
+
+ // 3. Execute some query: statement
+ logger.info("Execute statement");
+ statement = connection.createStatement();
+ answer = statement.executeQuery("SELECT * FROM AD");
+ // Loop through ResultSet a row at a time
+ while (answer.next()) {
+ final int adID = answer.getInt("AD_ID");
+ final int adCode = answer.getInt("AD_CODE");
+ final String description = answer.getString("DESCRIPTION");
+ logger.info("AD_ID: " + adID + " AD_CODE: " + adCode + " DESCRIPTION: " + description);
+ }
+ logger.info("Statement executed successfully");
+
+ // 4. Execute some query: prepared statement
+ logger.info("Execute prepared statement");
+ preparedStatement = connection.prepareStatement("SELECT * FROM AD");
+ preparedStatement.executeQuery();
+ // Loop through ResultSet a row at a time
+ while (answer.next()) {
+ final int adID = answer.getInt("AD_ID");
+ final int adCode = answer.getInt("AD_CODE");
+ final String description = answer.getString("DESCRIPTION");
+ logger.info("AD_ID: " + adID + " AD_CODE: " + adCode + " DESCRIPTION: " + description);
+ }
+ logger.info("Prepared statement executed successfully");
+ } catch (final ClassNotFoundException | SQLException e) {
+ logger.error("Program error: ", e);
+ } finally {
+ if (answer != null) {
+ // Explicitly close the cursor and connection. NOTE: IT IS NOT THE SAME AS "DECLARE CURSOR" OF SQL
+ // This is a cursor in program memory not in DBMS!!!
+ try {
+ answer.close(); // Cursor
+ } catch (final SQLException e) {
+ logger.error("Error while closing cursor: ", e);
+ }
+ }
+ if (statement != null) {
+ // I think closing ResultSet should be enough...
+ try {
+ statement.close();
+ } catch (final SQLException e) {
+ logger.error("Error while closing statement: ", e);
+ }
+ }
+ if (preparedStatement != null) {
+ // I think closing ResultSet should be enough...
+ try {
+ preparedStatement.close();
+ } catch (final SQLException e) {
+ logger.error("Error while closing prepared statement: ", e);
+ }
+ }
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (final SQLException e) {
+ logger.error("Error while closing connection: ", e);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package de.sql.tests;
+
+import java.beans.PropertyVetoException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+
+public class RawJDBCLambdaExample {
+ private static final Logger logger = LoggerFactory.getLogger(RawJDBCLambdaExample.class);
+
+ /**
+ * Carry out query – method returns a ResultSet object
+ *
+ */
+ private interface ExecuteStatement<TResult> {
+ TResult executeStatement(final Statement statement) throws SQLException;
+ }
+
+ private interface ExecuteResultSet<TResult> {
+ void executeResultSet(final TResult resultSet) throws SQLException;
+ }
+
+ public static void main(final String[] args) throws PropertyVetoException, SQLException {
+
+ // Just for fun, programmatic configuration.
+ final DataSource dataSource = RawJDBCLambdaExample.getDataSource();
+ try {
+ // The database connection (taken from c3p0 pool)
+ final Connection connection = dataSource.getConnection();
+
+ RawJDBCLambdaExample.executeQuery(
+ connection,
+ statement -> statement.executeQuery("SELECT * FROM AD"),
+ answer ->
+ {
+ // Loop through ResultSet a row at a time
+ while (answer.next()) {
+ final int adID = answer.getInt("AD_ID");
+ final int adCode = answer.getInt("AD_CODE");
+ final String description = answer.getString("DESCRIPTION");
+ logger.info("AD_ID: " + adID + " AD_CODE: "
+ + adCode + " DESCRIPTION: " + description);
+ }
+ }
+ );
+ } finally {
+ // Now we close the whole pool :)
+ ((ComboPooledDataSource)dataSource).close();
+ }
+ }
+
+ private static void executeQuery(final Connection connection,
+ final ExecuteStatement<ResultSet> executeStatement,
+ final ExecuteResultSet<ResultSet> executeResultSet) throws SQLException {
+
+ try (final Statement statement = connection.createStatement();
+ final ResultSet answer = executeStatement.executeStatement(statement)) {
+ executeResultSet.executeResultSet(answer);
+ }
+
+ // Explicitly close the cursor and connection. NOTE: IT IS NOT THE SAME AS
+ // "DECLARE CURSOR" OF SQL. This is a cursor in program memory not in DBMS!!!
+ // answer.close(); // Cursor
+
+ // NOTE: in this case I do not care if we hide Exceptions while closing!!!
+ }
+
+ /**
+ * Just for fun, programmatic configuration.
+ * @return
+ * @throws PropertyVetoException
+ */
+ private static DataSource getDataSource() throws PropertyVetoException {
+ final ComboPooledDataSource pool = new ComboPooledDataSource();
+
+ pool.setUser("root");
+ pool.setPassword("");
+ // We are going to use JDBC driver
+ pool.setDriverClass("com.mysql.jdbc.Driver");
+ pool.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/n2a?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8");
+ pool.setInitialPoolSize(5);
+ pool.setMaxPoolSize(35);
+ pool.setMinPoolSize(10);
+ pool.setAcquireIncrement(1);
+ pool.setAcquireRetryAttempts(5);
+ pool.setAcquireRetryDelay(1000);
+ pool.setAutomaticTestTable("con_test");
+ pool.setCheckoutTimeout(5000);
+
+ return pool;
+ }
+}
--- /dev/null
+package de.sql.tests;
+
+import java.beans.PropertyVetoException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+
+public class RawJDBCPoolExample {
+ private static final Logger logger = LoggerFactory.getLogger(RawJDBCPoolExample.class);
+
+ public static void main(final String[] args) throws PropertyVetoException {
+ // Just for fun, programmatic configuration.
+ final DataSource dataSource = getDataSource();
+
+ // 1. Using Statement
+ Connection connection = null;
+ Statement statement = null;
+ ResultSet answer = null;
+ try {
+ // The database connection (taken from c3p0 pool)
+ connection = dataSource.getConnection();
+ // Create a statement object for executing the query
+ statement = connection.createStatement();
+ // Carry out query – method returns a ResultSet object
+ answer = statement.executeQuery("SELECT * FROM AD");
+ // Loop through ResultSet a row at a time
+ while (answer.next()) {
+ final int adID = answer.getInt("AD_ID");
+ final int adCode = answer.getInt("AD_CODE");
+ final String description = answer.getString("DESCRIPTION");
+ logger.info("AD_ID: " + adID + " AD_CODE: " + adCode + " DESCRIPTION: " + description);
+ }
+
+ } catch (final SQLException e) {
+ logger.error("Using Statement: ", e);
+ } finally {
+ if (answer != null) {
+ // Explicitly close the cursor and connection. NOTE: IT IS NOT THE SAME AS "DECLARE CURSOR" OF SQL
+ // This is a cursor in program memory not in DBMS!!!
+ try {
+ answer.close(); // Cursor
+ } catch (final SQLException e) {
+ logger.error("Error while closing cursor: ", e);
+ }
+ }
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (final SQLException e) {
+ logger.error("Error while closing statement: ", e);
+ }
+ }
+ if (connection != null) {
+ // try {
+ // connection.close(); final I do not think, I should do it final when having a connection pool :/
+ // } catch (final SQLException e) {
+ // logger.error("Error while closing connection: ", e);
+ // }
+ }
+ }
+
+
+ // 2. Using PreparedStatement
+ PreparedStatement preparedStatement = null;
+ answer = null;
+ try {
+ // The database connection (taken from c3p0 pool)
+ connection = dataSource.getConnection();
+ // Create a statement object for executing the query
+ preparedStatement = connection.prepareStatement("SELECT * FROM AD");
+ // Carry out query – method returns a ResultSet object
+ answer = preparedStatement.executeQuery();
+ // Loop through ResultSet a row at a time
+ while (answer.next()) {
+ final int adID = answer.getInt("AD_ID");
+ final int adCode = answer.getInt("AD_CODE");
+ final String description = answer.getString("DESCRIPTION");
+ logger.info("AD_ID: " + adID + " AD_CODE: " + adCode + " DESCRIPTION: " + description);
+ }
+ } catch (final SQLException e) {
+ logger.error("Using PreparedStatement: ", e);
+ } finally {
+ if (answer != null) {
+ // Explicitly close the cursor and connection. NOTE: IT IS NOT THE SAME AS "DECLARE CURSOR" OF SQL
+ // This is a cursor in program memory not in DBMS!!!
+ try {
+ answer.close(); // Cursor
+ } catch (final SQLException e) {
+ logger.error("Error while closing cursor: ", e);
+ }
+ }
+ if (preparedStatement != null) {
+ // I think closing ResultSet should be enough...
+ try {
+ preparedStatement.close();
+ } catch (final SQLException e) {
+ logger.error("Error while closing prepared statement: ", e);
+ }
+ }
+ if (connection != null) {
+ // try {
+ // connection.close(); final I do not think, I should do it final when having a connection pool :/
+ // } catch (final SQLException e) {
+ // logger.error("Error while closing connection: ", e);
+ // }
+ }
+ }
+
+ // Now we close the whole pool :)
+ ((ComboPooledDataSource)dataSource).close();
+ }
+
+ /**
+ * Just for fun, programmatic configuration.
+ * @return
+ * @throws PropertyVetoException
+ */
+ private static DataSource getDataSource() throws PropertyVetoException {
+ final ComboPooledDataSource pool = new ComboPooledDataSource();
+
+ pool.setUser("root");
+ pool.setPassword("");
+ // We are going to use JDBC driver
+ pool.setDriverClass("com.mysql.jdbc.Driver");
+ pool.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/n2a?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8");
+ pool.setInitialPoolSize(5);
+ pool.setMaxPoolSize(35);
+ pool.setMinPoolSize(10);
+ pool.setAcquireIncrement(1);
+ pool.setAcquireRetryAttempts(5);
+ pool.setAcquireRetryDelay(1000);
+ pool.setAutomaticTestTable("con_test");
+ pool.setCheckoutTimeout(5000);
+
+ return pool;
+ }
+}
--- /dev/null
+package de.sql.tests;
+
+import java.beans.PropertyVetoException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcOperations;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsertOperations;
+import org.springframework.jdbc.core.simple.SimpleJdbcOperations;
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+
+public class RawSpringJDBCWithPoolExample {
+ private static final Logger logger = LoggerFactory.getLogger(RawSpringJDBCWithPoolExample.class);
+
+
+ public static void main(final String[] args) throws PropertyVetoException {
+ // Just for fun, programmatic configuration.
+ final DataSource dataSource = getDataSource();
+
+
+ final Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put("AD_ID", 1);
+
+
+ // 3. Using Spring JdbcTemplate
+ final JdbcOperations jdbcTemplate = new JdbcTemplate(dataSource);
+ jdbcTemplate.execute("SELECT * FROM AD");
+
+
+ // 4. Using SimpleJdbcTemplate
+ final SimpleJdbcOperations simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
+ final int deprecatedResult = simpleJdbcTemplate.queryForInt("SELECT * FROM AD", parameters);
+ logger.info("Deprecated result: " + deprecatedResult);
+
+
+ // 5. Using NamedParameterJdbcTemplate
+ final NamedParameterJdbcOperations namedParameterJdbcOperations = new NamedParameterJdbcTemplate(dataSource);
+ final int namedResult = namedParameterJdbcOperations.queryForInt("SELECT * FROM AD", parameters);
+ logger.info("Named result: " + namedResult);
+
+
+ // 6. Using Spring SimpleJdbcInsert
+ final SimpleJdbcInsertOperations simpleJdbcInsert = new SimpleJdbcInsert(dataSource);
+ simpleJdbcInsert.withTableName("ad");
+ simpleJdbcInsert.execute(parameters);
+
+ // Now we close the whole pool :)
+ ((ComboPooledDataSource)dataSource).close();
+ }
+
+ /**
+ * Just for fun, programmatic configuration.
+ * @return
+ * @throws PropertyVetoException
+ */
+ private static DataSource getDataSource() throws PropertyVetoException {
+ final ComboPooledDataSource pool = new ComboPooledDataSource();
+
+ pool.setUser("root");
+ pool.setPassword("");
+ // We are going to use the JDBC driver
+ pool.setDriverClass("com.mysql.jdbc.Driver");
+ pool.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/n2a?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8");
+ pool.setInitialPoolSize(5);
+ pool.setMaxPoolSize(35);
+ pool.setMinPoolSize(10);
+ pool.setAcquireIncrement(1);
+ pool.setAcquireRetryAttempts(5);
+ pool.setAcquireRetryDelay(1000);
+ pool.setAutomaticTestTable("con_test");
+ pool.setCheckoutTimeout(5000);
+
+ return pool;
+ }
+}
--- /dev/null
+package de.sql.tests;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * Spring context locator.
+ *
+ */
+public final class SpringContextLocator {
+ private static final Logger logger = LoggerFactory.getLogger(SpringContextLocator.class);
+
+ /** Spring ApplicationContext **/
+ private final ApplicationContext context;
+
+ /** Spring Context **/
+ private static final String SPRING_CONFIG_CONTEXT="spring-config.xml";
+
+
+ /**
+ * Private constructor. Singleton pattern.
+ */
+ private SpringContextLocator() {
+ final String[] factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
+
+ logger.info("Loading context files " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
+
+ this.context = new ClassPathXmlApplicationContext(factoryFiles);
+
+ logger.info("The context has been loaded successfully!! ");
+ }
+
+ /**
+ * SingletonHolder Thread-safety. To use an Enum class (see Effective Java
+ * Second Edition) if we need serialization and thread-safety.
+ */
+ private static class SingletonHolder {
+ public static final SpringContextLocator INSTANCE = new SpringContextLocator();
+ }
+
+ /**
+ * Return singleton instance. Thread-safety.
+ *
+ * @return Singleton instance.
+ */
+ public static SpringContextLocator getInstance() {
+ return SingletonHolder.INSTANCE;
+ }
+
+ /**
+ * Return bean from application context.
+ *
+ * @param beanId
+ * Bean's id.
+ * @return The bean instance.
+ */
+ public Object getBean(final String beanId) {
+ return this.context.getBean(beanId);
+ }
+}
--- /dev/null
+package de.sql.tests;
+
+import de.sql.tests.springtransaction.TransactionExample;
+
+public class SpringSQLExample {
+
+
+ public static void main(final String[] args) {
+
+ final TransactionExample test =
+ (TransactionExample) SpringContextLocator.getInstance().getBean("transactionExample");
+ test.doExample();
+
+ }
+}
--- /dev/null
+package de.sql.tests.springtransaction;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+
+public class NestedTransactionExample {
+ private static final Logger logger = LoggerFactory.getLogger(NestedTransactionExample.class);
+ private DataSource dataSource;
+
+ // Propagation.NESTED must be creating a SAVEPOINT to roll back when Exception
+ // (at least in InnoDB)
+ @Transactional(propagation=Propagation.NESTED)
+ public void doExample()
+ {
+ logger.info("BEGIN: NestedTransactionExample");
+
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
+ jdbcTemplate.execute("INSERT INTO AD VALUES (16)");
+
+ logger.info("END: NestedTransactionExample");
+ throw new RuntimeException("GOING TO REOLLBACK NESTED TRANSACTION");
+ }
+
+
+ public void setDataSource (final DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+}
--- /dev/null
+package de.sql.tests.springtransaction;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.transaction.annotation.Transactional;
+
+
+public class TransactionExample {
+ private static final Logger logger = LoggerFactory.getLogger(TransactionExample.class);
+ private DataSource dataSource;
+ private NestedTransactionExample nestedTransactionExample;
+
+ @Transactional
+ public void doExample()
+ {
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
+ jdbcTemplate.execute("INSERT INTO AD VALUES (16)");
+
+ try {
+ this.nestedTransactionExample.doExample();
+ } catch(final RuntimeException e) {
+ logger.error("Nested transaction performed roll back: ", e);
+ }
+ }
+
+ public void setDataSource (final DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ public void setNestedTransactionExample (
+ final NestedTransactionExample nestedTransactionExample) {
+ this.nestedTransactionExample = nestedTransactionExample;
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="trace" strict="true"
+ name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+ <Appenders>
+ <Appender type="Console" name="STDOUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+ </Appender>
+ </Appenders>
+ <Loggers>
+ <Root level="trace">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+</Configuration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/tx
+ http://www.springframework.org/schema/tx/spring-tx.xsd
+ http://www.springframework.org/schema/aop
+ http://www.springframework.org/schema/aop/spring-aop.xsd">
+
+
+ <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
+
+ <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
+ <property name="user" value="root"/>
+ <property name="password" value=""/>
+ <property name="driverClass" value="com.mysql.jdbc.Driver"/>
+ <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/n2a?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"/>
+ <property name="initialPoolSize" value="5"/>
+ <property name="maxPoolSize" value="35"/>
+ <property name="minPoolSize" value="10"/>
+ <property name="acquireIncrement" value="1"/>
+ <property name="acquireRetryAttempts" value="5"/>
+ <property name="acquireRetryDelay" value="1000"/>
+ <property name="automaticTestTable" value="con_test"/>
+ <property name="checkoutTimeout" value="5000"/>
+ </bean>
+
+ <bean id="transactionExample" class="de.spring.example.web.TransactionExample">
+ <property name="dataSource" ref="dataSource"/>
+ <property name="nestedTransactionExample" ref="testB"/>
+ </bean>
+
+ <bean id="nestedTransactionExample" class="de.spring.example.web.NestedTransactionExample">
+ <property name="dataSource" ref="dataSource"/>
+ </bean>
+
+</beans>