Persistent Sessions with JDBC and Tomcat - java

We have a cluster of Tomcat servers that share a common web server running mod_jk. We currently use sticky sessions to take care of session handling, but we would like to move to JDBC session sharing. Does anyone have a good resource or step-by-step solution to deal with this?
I was not sure if this question was meant for stackoverflow, serverfault, or DBA, but here it is. :)
EDIT:
I think the content of my question must be confusing. The sessions to which I am referring are user sessions (JSESSIONID), not connections to the database. What I want to do is use the database to handle the user sessions so that when one server in the cluster goes down, the transition to another server is seamless to the user. Right now, the user is logged out when an error on the server occurs.

Most of this is available in Tomcat documentation, see Persistent Manager Implementation.
You can also look at this.

Since you say JDBC, I'm assuming you mean in Java? Your question seems to have some ambiguity, so I'm not sure this is what you are looking for, but based on my understanding, I'll give it a shot. Anyway, I use connection pooling (Apache commons dbcp) and Spring, which makes it pretty easy.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/databasename"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
Then in the code I use Spring jdbctemplate, and with this setup, the connections to the database are pooled and reused. The datasource is managed as a Spring bean, then dependency-injected into where it is used. Spring handled the sharing of the jdbc sessions for you, and voila! Here is how I do the dependency injection with annotations:
private JdbcTemplate jdbcTemplate;
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
Even if you aren't using Spring for MVC or anything else, the Spring JDBC tools are really nice.

Related

Spring data JPA - Do not hard code password in XML file

I am writing a Spring Jar (Without Spring boot) which connects to database. Almost all the tutorials which I saw connects to Database using the spring XML and the password is hard coded in the XML file.
This is in no way allowed in production environment and way out of standards in terms of security.
Can someone please help me if there is a way to inject password from a method call which inturn retrieves the password from a secured vault and provides the password to datasource object in runtime.
something like below.
<bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
<property name="username" value="postgres" />
<property name="password" value=getPasswordfromSecureVault("username") />
<property name="suppressClose" value="true" />
<jdbc:initialize-database >
<jdbc:script location="create-tables.sql"/>
</jdbc:initialize-database>
Based on the spring boot tag that you have, I'll assume that you're using spring boot for your project. With spring boot, it is very easy to externalize configuration for your application. It also auto-configures your datasource with a connection pool if you use the starters they provide.
In your case, you could benefit from moving to using spring boot's Externalized Configuration.
What that would allow you to do is to use an environment variable to configure your spring application. For example, to configure your password, use the environment variable SPRING_DATASOURCE_PASSWORD. You could also use the Java option -Dspring.datasource.password=[password] when starting the application, for example:
java -jar -Dspring.datasource.password=password app.jar
If using docker containers, the environment variable way is generally my go to as it's very straight forward for people to understand.
If you really want to configure the password from a method call, you can do that too using java configuration. Create a bean of type DataSource and Spring should pick it up and use it.
#Configuration
class AppConfiguration {
#Bean
public DataSource dataSource() {
String password = // Get your password
return DataSourceBuilder.create().password(password).build();
}
}

Recover from idle in transaction with postgresql and BasicDataSource

I run postgresql with a transactional application where the stack is:
postgresql
tomcat
hibernate/spring
This is a production application where we have a bunch of customers connected at once. Each customer has it's own postgresql database but each customer also has many users.
Occasionally, i will get a situation where one of the customer databases locks up and I see idle in transaction tied to the processes for this customer.
postgres: customer1 customer1 127.0.0.1(59738) idle in transaction
When the database locks up the other databases continue to work fine. I can not get this to unlock without restarting the server application.
The problem is often triggered by various long running reports that the customer runs. I believe it is a locking/blocking issue where other users are also accessing the same data in the customer database.
This problem happens rarely and I can't ever reproduce it. But when it does happen it is a serious issue. Mostly I just want to recover from it.
Postgresql seems to function fine itself when this occurs. Like I can perform psql to the database and run queries. So, I think the problem or rather the solution centers around the data source.
I use the apache commons BasicDataSource.
<bean id="customer1DataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/customer1"/>
<property name="username" value="customer1"/>
<property name="password" value="password"/>
</bean>
So does anyone know of a setting in the basic data source that will kill these idle in transaction connections, throw an exception or allow them to recover somehow?

Spring transaction management using JDBC and Hibernate 4 together

We are using JPA (Hibernate 4) with Spring 4 managing the JTA transactions. Since there are parts of the application using JDBC to access the database as well, we need to make sure JDBC and JPA join the same transaction to see what the other changed before commit.
You can find a test case for these questions on GitHub https://github.com/abenneke/sandbox/tree/master/spring-hibernate4-transaction
To have JDBC and JPA join the same transaction and see the changes the other made, we had to use the TransactionAwareDataSourceProxy for Hibernate/JPA as well. With all the other transaction configuration around, this however seems to be redundant. Did we miss something? Or is this the suggested way to achieve the requirement?
Thank you!
I think you can achieve the same outcome with much less configuration hassle if you stock to Hibernate and your JTA DataSource while you use the Session.doWork for your JDBC code.
You don't need TransactionAwareDataSourceProxy, since you want to use Transaction services anyway and not call DAO classes outside of a transactional service.
You need to add:
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
and make sure you supply it to testEntityManager
<bean id="testEntityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="testDataSource">
...
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
Update
In one application we developed recently we too mixed JPA and JDBCTemplate and it worked nicely because Bitronix PoolingDataSource was instructed to always return the same connection for the current running thread.
For this you have to set the following Bitronix property:
shareTransactionConnections=true

java how to access a database that is in webserver across the internet?

If I have a database in a webserver(over the internet) and i have a java desktop application, in how many ways can i access that database. Please could you provide me with links for detailed article.
It depends on the database, but...
Most databases will allow you to access them remotely. You specify the URL and port when you set up your database connection in your Java program.
However, if you do not have control of the database, then this can be difficult. It is also a BIG security risk, unless you lock down the access via the HOSTS value of the user_id you are connecting with.
There are other work-around approaches, like VPNs, Tunnels and even fronting the database with a Web Service, but none of these are likely to give you the same level of access that the first option will.
Here is the link from oracle:
http://download.oracle.com/javase/tutorial/jdbc/index.html
Its very simple and easy to follow.
I recomend to use Hibernate, it easy to define any URL, to any database provider in Hibernate config file.
E.g
property name="driverClassName" value="com.mysql.jdbc.Driver"/>
property name="url" value="jdbc:mysql://189.234.223.89:3306/dbname"/>
property name="username" value="root"/>
property name="password" value="pwd"/>

how do I change persistence.xml at run time

I am new to openJPA.
I have a scenario where, depending upon the server where my application is running, I need to change the settings to persistance.xml.
For eg. if its running on Server A, then it should use different database(different url), different password etc. and if the application is running on Server B then it should use different information.
And could you also tell me, which way should it be done, using datasource or simply putting properties under persistence-unit.
FYI I am using WS app. server 7 and RAD 7.5
Any type of help would be highly appreciated.
You're using an application server so you don't need to set database connection settings in the persistence.xml file. You should be able to create a JNDI data source in your appserver and then use that. EAch server could have the data source have the same JNDI name and then there'll be no need for any persistence.xml differences.
Workshop, JPA, and DataSources seems particularly relevant to you. As does Setting up a JNDI data source in WebSphere 6.0/6.1 and WebSphere + JNDI + Spring Framework + Hibernate.
Are you using Spring? If so, then the problem is easy to solve: you don't put the data source information in your persistence.xml, you put it in your application context and that'll have different configuration on each server.
For example:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:database.properties"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.class}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
and each server could have a different database.properties file on each server (where each is in the classpath somewhere in this example):
database.username=scratch
database.password=scratch
database.class=oracle.jdbc.OracleDriver
database.url=jdbc:oracle:thin:#localhost:1521:XE
Changing persistence.xml at runtime is going to be problematic as that's not really how JPA is designed.
Of course, you can use JNDI data sources with Spring also.

Categories

Resources