Files
spring-cloud-static/spring-cloud-aws/2.0.0.M2/multi/multi__data_access_with_jdbc.html
2017-11-17 04:34:49 +00:00

187 lines
38 KiB
HTML

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>7.&nbsp;Data Access with JDBC</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-aws.html" title="Spring Cloud AWS"><link rel="up" href="multi_spring-cloud-aws.html" title="Spring Cloud AWS"><link rel="prev" href="multi__caching.html" title="6.&nbsp;Caching"><link rel="next" href="multi__sending_mails.html" title="8.&nbsp;Sending mails"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">7.&nbsp;Data Access with JDBC</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__caching.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="multi__sending_mails.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_data_access_with_jdbc" href="#_data_access_with_jdbc"></a>7.&nbsp;Data Access with JDBC</h1></div></div></div><p>Spring has a broad support of data access technologies built on top of JDBC like <code class="literal">JdbcTemplate</code> and dedicated ORM (JPA,
Hibernate support). Spring Cloud AWS enables application developers to re-use their JDBC technology of choice and access the
<a class="link" href="http://aws.amazon.com/rds/" target="_top">Amazon Relational Database Service</a> with a declarative configuration. The main support provided by Spring
Cloud AWS for JDBC data access are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Automatic data source configuration and setup based on the Amazon RDS database instance.</li><li class="listitem">Automatic read-replica detection and configuration for Amazon RDS database instances.</li><li class="listitem">Retry-support to handle exception during Multi-AZ failover inside the data center.</li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_configuring_data_source" href="#_configuring_data_source"></a>7.1&nbsp;Configuring data source</h2></div></div></div><p>Before using and configuring the database support, the application has to include the respective module dependency
into its Maven configuration. Spring Cloud AWS JDBC support comes as a separate module to allow the modularized use of the
modules.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_maven_dependency_configuration_2" href="#_maven_dependency_configuration_2"></a>7.1.1&nbsp;Maven dependency configuration</h3></div></div></div><p>The Spring Cloud AWS JDBC module comes as a standalone module and can be imported with the following dependency declaration.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;dependency&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;groupId&gt;</span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/groupId&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;artifactId&gt;</span>spring-cloud-aws-jdbc<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/artifactId&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;version&gt;</span>{spring-cloud-version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/version&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/dependency&gt;</span></pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_basic_data_source_configuration" href="#_basic_data_source_configuration"></a>7.1.2&nbsp;Basic data source configuration</h3></div></div></div><p>The data source configuration requires the security and region configuration as a minimum allowing Spring Cloud AWS to retrieve
the database metadata information with the Amazon RDS service. Spring Cloud AWS provides an additional <code class="literal">jdbc</code> specific namespace
to configure the data source with the minimum attributes as shown in the example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;beans</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns:xsi</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns:jdbc</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://www.springframework.org/schema/cloud/aws/jdbc"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://www.springframework.org/schema/beans"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xsi:schemaLocation</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://www.springframework.org/schema/cloud/aws/jdbc
http://www.springframework.org/schema/cloud/aws/jdbc/spring-cloud-aws-jdbc.xsd"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;aws-context:context-credentials&gt;</span>
...
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/aws-context:context-credentials&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;aws-context:context-region</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">region</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"..."</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">/&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;jdbc:data-source</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">db-instance-identifier</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myRdsDatabase"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">password</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"${rdsPassword}"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/jdbc:data-source&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/beans&gt;</span></pre><p>The minimum configuration parameters are a unique <code class="literal">id</code> for the data source, a valid <code class="literal">db-instance-identifier</code> attribute
that points to a valid Amazon RDS database instance. The master user password for the master user. If there is another
user to be used (which is recommended) then the <code class="literal">username</code> attribute can be set.</p><p>With this configuration Spring Cloud AWS fetches all the necessary metadata and creates a
<a class="link" href="http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html" target="_top">Tomcat JDBC pool</a> with the default properties. The data source
can be later injected into any Spring Bean as shown below:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Service</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> SimpleDatabaseService <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> DatabaseService {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> JdbcTemplate jdbcTemplate;
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> SimpleDatabaseService(DataSource dataSource) {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.jdbcTemplate = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> JdbcTemplate(dataSource);
}
}</pre><p>It is possible to qualify the data source injection point with an <code class="literal">@Qualifier</code> annotation to allow multiple data source
configurations inside one application context and still use auto-wiring.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_data_source_pool_configuration" href="#_data_source_pool_configuration"></a>7.1.3&nbsp;Data source pool configuration</h3></div></div></div><p>Spring Cloud AWS creates a new Tomcat JDBC pool with the default properties. Often these default properties do not meet the
requirements of the application with regards to pool size and other settings. The data source configuration supports the configuration
of all valid pool properties with a nested XML element. The following example demonstrates the re-configuration of the data source
with custom pool properties.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;beans</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">..&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;aws-context:context-credentials&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">...</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;/aws-context:context-credentials&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;aws-context:context-region</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">region</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"..."</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">/&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;jdbc:data-source</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">db-instance-identifier</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myRdsDatabase"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">password</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"${rdsPassword}"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;jdbc:pool-attributes</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">initialSize</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"1"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">maxActive</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"200"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">minIdle</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"10"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">testOnBorrow</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"true"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">validationQuery</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"SELECT 1"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/jdbc:data-source&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/beans&gt;</span></pre><p>A full list of all configuration attributes with their value is available <a class="link" href="http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html" target="_top">here</a>.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_configuring_data_source_with_java_config" href="#_configuring_data_source_with_java_config"></a>7.2&nbsp;Configuring data source with Java config</h2></div></div></div><p>Spring Cloud AWS also supports the configuration of the data source within an <code class="literal">@Configuration</code> class. The
<code class="literal">org.springframework.cloud.aws.jdbc.config.annotation.EnableRdsInstance</code> annotation can be used to configure one data
source. Multiple ones can be used to configure more then one data source. Each annotation will generate exactly one
data source bean.</p><p>The class below shows a data source configuration inside a configuration class</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
<em><span class="hl-annotation" style="color: gray">@EnableRdsInstance(dbInstanceIdentifier = "test",password = "secret", readReplicaSupport = true)</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> ApplicationConfiguration {
}</pre><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>The configuration attributes are the same in the XML element. The required attributes are also the same
for the XML configuration (the <code class="literal">dbInstanceIdentifier</code> and <code class="literal">password</code> attribute)</p></td></tr></table></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_java_based_data_source_pool_configuration" href="#_java_based_data_source_pool_configuration"></a>7.2.1&nbsp;Java based data source pool configuration</h3></div></div></div><p>It is also possible to override the pool configuration with custom values. Spring Cloud AWS provides a
<code class="literal">org.springframework.cloud.aws.jdbc.config.annotation.RdsInstanceConfigurer</code> that creates a
<code class="literal">org.springframework.cloud.aws.jdbc.datasource.DataSourceFactory</code> which might contain custom pool attributes. The next
examples shows the implementation of one configurer that overrides the validation query and the initial size.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
<em><span class="hl-annotation" style="color: gray">@EnableRdsInstance(dbInstanceIdentifier = "test",password = "secret")</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> ApplicationConfiguration {
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> RdsInstanceConfigurer instanceConfigurer() {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RdsInstanceConfigurer() {
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> DataSourceFactory getDataSourceFactory() {
TomcatJdbcDataSourceFactory dataSourceFactory = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TomcatJdbcDataSourceFactory();
dataSourceFactory.setInitialSize(<span class="hl-number">10</span>);
dataSourceFactory.setValidationQuery(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"SELECT 1 FROM DUAL"</span>);
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> dataSourceFactory;
}
};
}
}</pre><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>This class returns an anonymous class of type <code class="literal">org.springframework.cloud.aws.jdbc.config.annotation.RdsInstanceConfigurer</code>,
which might also of course be a standalone class.</p></td></tr></table></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_configuring_data_source_in_spring_boot" href="#_configuring_data_source_in_spring_boot"></a>7.3&nbsp;Configuring data source in Spring Boot</h2></div></div></div><p>The data sources can also be configured using the Spring Boot configuration files. Because of the dynamic number of
data sources inside one application, the Spring Boot properties must be configured for each data source.</p><p>A data source configuration consists of the general property name <code class="literal">cloud.aws.rds.&lt;instanceName&gt;</code> for the data source identifier
following the sub properties for the particular data source where <code class="literal">instanceName</code> is the name of the concrete instance. The table below
outlines all properties for a data source using <code class="literal">test</code> as the instance identifier.</p><div class="informaltable"><table style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; "><colgroup><col class="col_1"><col class="col_2"><col class="col_3"></colgroup><thead><tr><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">property</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">example</th><th style="border-bottom: 0.5pt solid ; " align="left" valign="top">description</th></tr></thead><tbody><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>cloud.aws.rds.test</p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">&nbsp;</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>The configuration property that configures a data source with the name test</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>cloud.aws.rds.test.password</p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>verySecret</p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>The password for the db instance test</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>cloud.aws.rds.test.username</p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>admin</p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>The username for the db instance test (optional)</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>cloud.aws.rds.test.readReplicaSupport</p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>true</p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>If read-replicas should be used for the data source (see below)</p></td></tr><tr><td style="border-right: 0.5pt solid ; " align="left" valign="top"><p>cloud.aws.rds.test.databaseName</p></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><p>fooDb</p></td><td style="" align="left" valign="top"><p>Custom database name if the default one from rds should not be used</p></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_read_replica_configuration" href="#_read_replica_configuration"></a>7.4&nbsp;Read-replica configuration</h2></div></div></div><p>Amazon RDS allows to use <a class="link" href="http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html" target="_top">MySQL read-replica</a>
instances to increase the overall throughput of the database by offloading read data access to one or more read-replica
slaves while maintaining the data in one master database.</p><p>Spring Cloud AWS supports the use of read-replicas in combination with Spring read-only transactions. If the read-replica
support is enabled, any read-only transaction will be routed to a read-replica instance while using the master database
for write operations.</p><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>Using read-replica instances does not guarantee strict <a class="link" href="http://en.wikipedia.org/wiki/ACID" target="_top">ACID</a> semantics for the database
access and should be used with care. This is due to the fact that the read-replica might be behind and a write might not
be immediately visible to the read transaction. Therefore it is recommended to use read-replica instances only for transactions that read
data which is not changed very often and where outdated data can be handled by the application.</p></td></tr></table></div><p>The read-replica support can be enabled with the <code class="literal">read-replica</code> attribute in the datasource configuration.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;beans</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">..&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;jdbc:data-source</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">db-instance-identifier</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"RdsSingleMicroInstance"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">password</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"${rdsPassword}"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">read-replica-support</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"true"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/jdbc:data-source&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/beans&gt;</span></pre><p>Spring Cloud AWS will search for any read-replica that is created for the master database and route the read-only transactions
to one of the read-replicas that are available. A business service that uses read-replicas can be implemented like shown
in the example.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Service</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> SimpleDatabaseService {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> JdbcTemplate jdbcTemplate;
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> SimpleDatabaseService(DataSource dataSource) {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.jdbcTemplate = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> JdbcTemplate(dataSource);
}
<em><span class="hl-annotation" style="color: gray">@Transactional(readOnly = true)</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Person loadAll() {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// read data on the read replica</span>
}
<em><span class="hl-annotation" style="color: gray">@Transactional</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> updatePerson(Person person) {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// write data into database</span>
}
}</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_failover_support" href="#_failover_support"></a>7.5&nbsp;Failover support</h2></div></div></div><p>Amazon RDS supports a <a class="link" href="http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html" target="_top">Multi-AZ</a> fail-over if
one availability zone is not available due to an outage or failure of the primary instance. The replication is synchronous
(compared to the read-replicas) and provides continuous service. Spring Cloud AWS supports a Multi-AZ failover with a retry
mechanism to recover transactions that fail during a Multi-AZ failover.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>In most cases it is better to provide direct feedback to a user instead of trying potentially long and frequent retries within
a user interaction. Therefore the fail-over support is primarily useful for batch application or applications where the
responsiveness of a service call is not critical.</p></td></tr></table></div><p>The Spring Cloud AWS JDBC module provides a retry interceptor that can be used to decorate services with an interceptor.
The interceptor will retry the database operation again if there is a temporary error due to a Multi-AZ failover. A Multi-AZ
failover typically lasts only a couple of seconds, therefore a retry of the business transaction will likely succeed.</p><p>The interceptor can be configured as a regular bean and then be used by a pointcut expression to decorate the respective
method calls with the interceptor. The interceptor must have a configured database to retrieve the current status (if it
is a temporary fail-over or a permanent error) from the Amazon RDS service.</p><p>The configuration for the interceptor can be done with a custom element from the Spring Cloud AWS jdbc namespace and
will be configured like shown:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;beans</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">..&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;jdbc:retry-interceptor</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">id</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myInterceptor"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">db-instance-identifier</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myRdsDatabase"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">max-number-of-retries</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"10"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/beans&gt;</span></pre><p>The interceptor itself can be used with any Spring advice configuration to wrap the respective service. A pointcut
for the services shown in the chapter before can be defined as follows:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;beans</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">..&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;aop:config&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">&lt;aop:advisor</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">advice-ref</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myInterceptor"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">pointcut</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"bean(simpleDatabaseService)"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">order</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"1"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/aop:config&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/beans&gt;</span></pre><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>It is important that the interceptor is called outside the transaction interceptor to ensure that the whole transaction
will be re-executed. Configuring the interceptor inside the transaction interceptor will lead to a permanent error because
the broken connection will never be refreshed.</p></td></tr></table></div><p>The configuration above in combination with a transaction configuration will produce the following proxy configuration
for the service.</p><div class="informalfigure"><div class="mediaobject"><img src="images/jdbc-retry-interceptor.png" alt="Retry interceptor"></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_cloudformation_support" href="#_cloudformation_support"></a>7.6&nbsp;CloudFormation support</h2></div></div></div><p>Spring Cloud AWS supports database instances that are configured with CloudFormation. Spring Cloud AWS can use the logical
name inside the database configuration and lookup the concrete database with the generated physical resource name. A database
configuration can be easily configured in CloudFormation with a template definition that might look like the following
example.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"myRdsDatabase"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Type"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AWS::RDS::DBInstance"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Properties"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AllocatedStorage"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"5"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"DBInstanceClass"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"db.t1.micro"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"DBName"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"test"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Engine"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"mysql"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"MasterUsername"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"admin"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"MasterUserPassword"</span>: {<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Ref"</span>:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"RdsPassword"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
...
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"readReplicaDatabase"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Type"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AWS::RDS::DBInstance"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Properties"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AllocatedStorage"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"5"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"SourceDBInstanceIdentifier"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Ref"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"myRdsDatabase"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"DBInstanceClass"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"db.t1.micro"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span></pre><p>The database can then be configured using the name set in the template. Also, the read-replica can
be enabled to use the configured read-replica database in the application. A configuration to use the configured
database is outlined below:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;beans&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;aws-context:stack-configuration/&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;jdbc:data-source</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">db-instance-identifier</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myRdsDatabase"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">password</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"${rdsPassword}"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">read-replica-support</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"true"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">/&gt;</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;/beans&gt;</span></pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_database_tags" href="#_database_tags"></a>7.7&nbsp;Database tags</h2></div></div></div><p>Amazon RDS instances can also be configured using RDS database specific tags, allowing users to configure database specific
configuration metadata with the database. Database instance specific tags can be configured using the <code class="literal">user-tags-map</code> attribute
on the <code class="literal">data-source</code> element. Configure the tags support like in the example below:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">&lt;jdbc:data-source</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">db-instance-identifier</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"myRdsDatabase"</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">password</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"${rdsPassword}"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">user-tags-map</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"dbTags"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /&gt;</span></pre><p>That allows the developer to access the properties in the code using expressions like shown in the class below:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> SampleService {
<em><span class="hl-annotation" style="color: gray">@Value("#{dbTags['aws:cloudformation:aws:cloudformation:stack-name']}")</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> String stackName;
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The database tag <code class="literal">aws:cloudformation:aws:cloudformation:stack-name</code> is a default tag that is created if the
database is configured using CloudFormation.</p></td></tr></table></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__caching.html">Prev</a>&nbsp;</td><td width="20%" align="center">&nbsp;</td><td width="40%" align="right">&nbsp;<a accesskey="n" href="multi__sending_mails.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.&nbsp;Caching&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-aws.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;8.&nbsp;Sending mails</td></tr></table></div></body></html>