My app is made of a Spring rest controller calling a service using redis.
I am using spring boot starter redis 1.2.5 and I have defined a template in my beans.xml file:
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${spring.redis.host}"
p:use-pool="true"
p:port="${spring.redis.port}"
/>
<bean id="redisTemplateForTransaction" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory"
p:keySerializer-ref="stringRedisSerializer"
p:valueSerializer-ref="jsonRedisSerializerForTransaction"
p:enableTransactionSupport="true">
<qualifier value="redisTemplateForTransaction" />
</bean>
When I launch more than 8 queries my app blocks. I understand I have reached the default number of connections in the pool.
Why aren't the connections returned automatically at the end of the request processing ?
How to work in a transactional mode so that any incoming request will get its redis connection and return it at the end of the processing ?
You need to enable transaction management for your application by providing a PlatformTransactionManager bean.
The easiest way to do so is adding #EnableTransactionManagement to your Spring Boot application. If that's not possible, configure a PlatformTransactionManager bean. Reusing an existing DataSourceTransactionManager is the easiest way. If you do not use a JDBC-compliant database, simply drop in a H2 in-memory database.
If you want to use a JTA transaction manager, see this blog post: https://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/
HTH, Mark
Related
I have an application that connects with a Database. The DB could be SQL Server, PG, etc. I need to configure the application to use SSL now.
I am using hibernate and configuring the datasources accordingly. I am using org.apache.commons.dbcp2.BasicDataSource as of now.
I understand that in order to connect to SQL Server using SSL, I need to use SQLServerDataSource. But then it would not work if someone decides to use PG database.
Is there any way to configure the individual datasources dynamically? Or is there a common datasource that I can use irrespective of the jdbc driver (mssql or pg) provided at the runtime?
Passing the JVM parameters like -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword modifying the jdbc connection string are not an option.
I am using Spring (mostly XML configs) to bootstrap the application.
In Spring you can replace the used data source class using profiles.
The key idea is that you can provide multiple definition of the same bean. Those definitions would be enclosed in separate <beans> element with different profile attribute.
<beans profile="embedded-db">
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
<jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>
</jdbc:embedded-database>
</beans>
<beans profile="sql-server">
<!-- Configuration of you SQL Server data source -->
</beans>
<beans profile="postgresql">
<!-- Configuration of you PostgreSQL data source -->
</beans>
When running the application the configuration property spring.profiles.active needs to be set to choose one or more of the profiles.
Unfortunately, modern Spring documentation doesn't provide much help in setting up XML configs. I think they are now considered legacy.
In Spring, beans can be configured to be lazily initialized. Spring Batch jobs are also (Spring-managed) beans. That is, when I configure something like
<sb:job id="dummyJob" job-repository="jobRepository">
<sb:step id="dummyStep">
<sb:tasklet ref="dummyTasklet" />
</sb:step>
</sb:job>
I actually configure a new (Job-typed) bean inside the Spring container.
My issue is I really want my Job beans to be lazily initialized. As they are regular Spring-managed beans, I'd expect I can instruct the Spring context to make them lazy. This is because I have a large number of beans and there are many cases in which, during one execution of my Spring-based application, I only run one job.
But there's no lazy-init property I can set on my <sb:job... \> configuration. Is there any way I can force lazy initialization? If I configure my <beans\> root with default-lazy-init="true", will this also apply to the Job beans?
You have two options here:
Configure your job manually. This would allow you to use the regular lazy-init attributes Spring exposes.
Use the JobScope now available in Spring Batch 3. Spring Batch 3 will be available soon, but the JobScope was available in the last milestone.
Just to elaborate on Michael Minella's answer.
I had a similar requirement to lazy initialize the job repository.
I am working with Spring Batch 2.1.9.
The following is working for me.
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
lazy-init="true">
<property name="dataSource" ref="jobDataSource"/>
<property name="transactionManager" ref="jobTransactionManager"/>
</bean>
Note one pitfall I had run into: do not set the databaseType i.e. avoid the following:
<property name="databaseType" value="SQLSERVER"/>
This is bad because it disable the auto-discovery of the database type and breaked my JUnits that works on H2.
How can i configure a default query timeout in application level. I am using spring , hibernate and db2 as a backend. Setting the timeout in datasource level is not an option as we are using an old version of IBM websphere. I tried configuring defaultTimeout in transaction manager but that is not helping. I don't want to integrate c3p0 connection pooling also. Is there any other options that hibernate provide for setting a global query timeout in application level , if yes how that is configured .
Thanks in advance
Here is the spring config configuration.
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<property name="queryTimeout" value="60"/>
</bean>
Somebody knows an example with EJB3 and Mybatis where the container controls the transaction, the only part of code I founded was:
SQLMapConfig.xml
<transactionManager type="EXTERNAL">
<property name="SetAutoCommitAllowed" value="false"/>
<dataSource type="JNDI">
<property name="DataSource" value="java:comp/env/jdbc/sisds"/>
</dataSource>
</transactionManager>
But I have many questions, for example,
When the container make the commit?
When the container release the session to the pool?
Thanks in Advance
The container commits the transaction based on how your EJBs are configured. If you are using bean managed transactions, then you have to manage the UserTransaction yourself.
Regardless, you have to manage the MyBatis SqlSession yourself. Setting the tx type to EXTERNAL (MANAGED in Mybatis 3), simply means that MyBatis never calls commit on the DB connection - it relies on the container to commit.
It seems that Hibernate transactional cache mode requires the use of a JTA transaction manager. In an app server such as Glassfish, Weblogic, etc, Spring can use the JTA transaction manager. Tomcat does not have a JTA transaction manager.
Is there one that people use in this scenario? Or do people just not use transactional cache mode with Tomcat?
It depends on you ORM implementation, for example for JPA Spring has a transaction manager for using outside Java EE containers. here's how you declare it:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
I usually use annotations to demarcate transaction boundaries (with #Transaction), to do this you just have to add to the configuration file this other line:
<tx:annotation-driven transaction-manager="transactionManager" />
present in this XSD namespace: "http://www.springframework.org/schema/tx"
Atomikos is one JTA transaction manager that can be bundled with your app to work in a Tomcat deployment.