简体   繁体   中英

PgPool Load balancing for Java/JDBC application

After setting up all the possible settings of PgPool on CentOS, when I tested it using my Java application, I found that it is not working.
After reading manual on internet (you can find here ), I found that it will not work for JDBC statements if they have been set to false (for auto commit).
Since I am using Hibernate, I am quiet sure that it is using transaction to set the values.
My question is, if this is true, which method of is useful to replicate my databases. I hear about parallel mode, but I am not sure whether it will work for Java application. Can anybody guide and provide me samples for it?

If by parallel mode what you meant is the transaction isolation level, from this page you can see that PostgreSQL supports 4 level of isolations , and it is configurable from hibernate by setting the property: hibernate.connection.isolation to 1, 2, 4, or 8, from lower level to the highest.

Read committed is the default isolation level in PostgreSQL, one level above dirty read.

Serialization is the highest level and it is very expensive, because if 2 transactions are to be made on the same table, there will be a lock, if locking happens more than the time out that was set on the Database/Hibernate, then it will throw a time out exception.

Not sure if you have heard about them but following are frameworks that can be used with hibernate to improve performance:

  • C3P0 for a more advanced connection pooling
  • Ehcache for boosting performance by enabling cache

They are easy to configure and do not depends on OS. I did not have any experience with PgPool so I can't give comments on performance comparison.

Following are the sample hibernate settings that you might want to try:

<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.connection.isolation">4</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider</prop>
<prop key="net.sf.ehcache.configurationResourceName">WEB-INF/ehcache.xml</prop>

I hope this can help you in optimizing your application in regards of database transactions. There are a lot more that you can actually check eg table indexing, or using a profiler to find out which transactions cost the most.

Modification transactions at the end of business methods work as you describe: a BEGIN/END block is created containing all modification queries that are either all committed or rolled back.

This is done by setting autocommit to false, but this does not mean that all queries made by Hibernate are done in this mode. The same query depending on the required isolation mode might be executed either in auto-commit or non auto-commit mode.

For the usual case of a transaction in READ_COMMITED mode, queries like find by Id or named queries will run in it's own database transaction with auto-commit true ( and so without a BEGIN/END block).

Find by Ids and other read queries will only trigger a BEGIN block if they are run in at least REPEATABLE_READ isolation mode.

This mean that if you use the default REPEATABLE_READ isolation mode, the load balancing will work fine because most select queries will run with in auto-commit = true.

You can confirm this by logging all SQL queries sent to the database using for example log4jdbc . This will print all the SQL actually sent to the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM