I'm trying to find the best way to create a dataSource in Spring for connecting to a Google Cloud SQL instance.
I'm currently using:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.GoogleDriver" />
<property name="url" value="jdbc:google:mysql://myappid:instanceId/mydb?user=myuser" />
<property name="username" value="myuser" />
<property name="password" value="mypassword" />
</bean>
However, I'm a little concerned about using the DriverManagerDataSource provided by Spring as it's documentation says it creates a new connection for every call.
Before migrating over to App Engine I was using a connection pool called BoneCP - however it uses classes that are restricted by App Engine. Is there a connection pool or some other data source class that is recommended to be used with Google Cloud SQL?
Try c3p0 or commons-dbcp. They both implement javax.sql.Datasource which is whitelisted by app-engine.
Example on commons-dbcp:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.GoogleDriver" />
<property name="url" value="jdbc:google:mysql://myappid:instanceId/mydb?user=myuser" />
<property name="username" value="myuser" />
<property name="password" value="mypassword" />
<property name="validationQuery" value="SELECT 1"/>
</bean>
Related
I am having some trouble configuring Spring to use BATCH_* tables hosted by MySQL.
I created the tables ok according to docs however it looks like the code is trying to get a sequence number using the Oracle flavour function.
The error I get is:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table 'BATCH_JOB_SEQ' in field list
But this is hiding the real problem. I debugged it and its trying to run this code:
select " + getIncrementerName() + ".nextval from dual";
Which is obviously Oracle dialect. I notice that there exists the correct incrementer in my environment here:
org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer()
but its calling
org.springframework.jdbc.support.incrementer.OracleMaxValueIncrementer()
I have setup my data source thus:
<bean id="springDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.252.205.5:3306/MASKNG" />
<property name="username" value="MASKNG" />
<property name="password" value="maskng" />
</bean>
Anyone have an ideas as this is a show stopper for us atm
Well, well, I really should RTM a little more...you just have to tell the jobRepository bean what type of DB you are using
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="springDataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="validateTransactionState" value="${jobRepository.validationTransactionState:true}" />
<property name="isolationLevelForCreate" value="${jobRepository.isolationLevelForCreate}" />
<!-- <property name="databaseType" value="oracle" /> -->
<property name="databaseType" value="mysql" />
<property name="tablePrefix" value="BATCH_" />
<property name="lobHandler" ref="lobHandler"/>
</bean>
I have implemented spring jdbc in my project. I am just curious to know how connection pooling in handled in spring jdbc? If spring is taking care of connections, then where can I specify the max number of connections allowed for my application?
Another question is how is connection pooling handled in simple jdbc.
Please clarify.
You can use own custom datasource, like this:
<bean id="springDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="url" value="jdbc:oracle:thin:#localhost:1521:SPRING_TEST" />
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="20" />
<property name="maxActive" value="30" />
</bean>
//Dao class configuration in spring
<bean id="EmployeeDatabaseBean" class="com.test.EmployeeDAOImpl">
<property name="dataSource" ref="springDataSource"/>
</bean>
Official documentation
Here or here described pretty simple.
I currently use this configuration for my projects:
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="URL" ...
<property name="user" ...
<property name="password" ...
<property name="connectionCachingEnabled" value="true" />
And it works fine, pretty fast.
I happened to see, on an old project (spring 2.5) this configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url"...
<property name="username" ...
<property name="password" ...
</bean>
From documentation it would seem that this last option does not make use of a connection pool. I see no reason to use this configuration over mine, but it still exists so I am curious: where's the advantage/limitation?
1st configuration is oracle specific, whereas 2nd configuration is generic. You can explicitly define driver class.
This is the only major difference I can see in them other than connection pool support of OracleDataSource.
You can use it for generic behavior as mentioned below:
<bean id="baseDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
abstract="true">
<property name="username" value="user"/>
<property name="password" value="pwd" />
</bean>
<bean id="mySqlDataSource" parent="baseDataSource">
<property name="driverClassName" value="${mySQL.driver}" />
<property name="url" value="${mySQL.url}"/>
</bean>
<bean id="oracleDataSource" parent="baseDataSource">
<property name="driverClassName" value="${oracle.driver}" />
<property name="url" value="${oracle.url}"/>
</bean>
Property values you can externalized.
You can explore Apache Jakarta Commons DBCP which has all the features of DriverManagerDataSource
along with connection pool feature.
I'm using a spring datasource and is unable to connect to Oracle AQ Queue.
Connection connection = null;
AQSession aqSess = null;
connection = ds.getConnection();
connection.setAutoCommit(false);
DataSourceUtils.getTargetConnection(connection);
Class.forName("oracle.AQ.AQOracleDriver");
aqSess = AQDriverManager.createAQSession(connection);
aqSession = aqSess;
But still get this: oracle.jms.AQjmsException: JMS-112: Connection is invalid any tips would be appreciated.
<bean id="myId" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#myIpAddress:dev"/>
<property name="username" value="user"/>
<property name="password" value="pass"/>
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="2"/>
<property name="maxIdle" value="8"/>
<property name="maxActive" value="30"/>
<property name="maxWait" value="60000"/>
</bean>
AQException: oracle.AQ.AQException: JMS-112: Connection is invalid
at oracle.AQ.AQDriverManager.createAQSession(AQDriverManager.java:193)
I fixed my problem using the following code:
OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
Recording it here as an answer in case others find this question when having a similar problem.
Oracle AQ doesn't match with BasicDataSource
useOracleDataSource instead
but if you want to use BasicDataSource:
In many application server environments the JDBC connection is wrapped
in an implementation specific class that delegates to the underlying
native JDBC connection. Oracle's AQ connection factory needs the
native Oracle connection and will throw an "oracle.jms.AQjmsException:
JMS-112: Connection is invalid" exception if the connection is wrapped
by a foreign class. To solve this problem you can specify a
NativeJdbcExtractor that can be used to unwrap the connection. Spring
provides a number of implementations to match the application server
environment. Here is an example for specifying a NativeJdbcExtractor.
<orcl:aq-jms-connection-factory id="connectionFactory"
use-local-data-source-transaction="true"
native-jdbc-extractor="dbcpNativeJdbcExtractor" 1
data-source="dataSource" />
<bean id="dbcpNativeJdbcExtractor"
class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
https://docs.spring.io/spring-data/jdbc/old-docs/2.0.0.BUILD-SNAPSHOT/reference/html/orcl.streamsaq.html
At this moment I'm using DriverManagerDataSource with #Transactional annotation to manage transactions. But all transactions are very very slow, probably because data source open and close connection to db each time.
What data source should I use to speed up transaction?
I am using in my application combination of two approaches. the first one is c3p0 connection pooling, its almost the same solution as chkal sugested. The second approach is to use Spring lazyConnectionDataSourceProxy, which creates lazy loading proxy that loads connection only if you hit the database. This is very useful, when you have second level cache and you are only reading cached data and queries - database wont be hit, and you don't need to acquire connection (which is pretty expensive).
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- Pool properties -->
<property name="minPoolSize" value="5" />
<property name="initialPoolSize" value="10" />
<property name="maxPoolSize" value="50" />
<property name="maxStatements" value="50" />
<property name="idleConnectionTestPeriod" value="120" />
<property name="maxIdleTime" value="1200" />
</bean>
<bean name="lazyConnectionDataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="dataSource" />
</bean>
DriverManagerDataSource isn't actually a connection pool and should only be used for testing. You should try BasicDataSource from Apache Commons DBCP. Something like:
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>