2010-09-08

Tomcat connection pooling

Dobavljanje konekcije je skupo. Pravljenje globalne konekcije je loše rešenje u uslovima kad postoji više niti (npr. u web aplikaciji) jer se po jednoj konekciji obavlja jedna transakcija, što znači da ako više niti deli istu konekciju one će sa conn.commit() i conn.rollback() da smetaju međusobno. Rešenje je da se ima Connection Pool da kad se zahteva konekcija da se ne prvi novi objekat, a kad se povozove conn.close() da se konekcija ne zatvori već se vrati u pool i reciklira.

Tomcat ima ugrađenu podršku za poolove. U webapp/WEB-INF/web.xml (webapp ako je projekat pravljen pomoću Maven-a) fajlu se definiše resurs preko sledećeg taga:


<resource-ref>
<res-ref-name>jdbc/bankDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>


Ovde se definiše ime resursa, njegov tip i da će autentifikaciju obaviti servlet container (tomcat)

Zatim se u webapp/META-INF/context.xml daje definicija resursa:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/MyApp-1.0-SNAPSHOT">
<Resource
name="jdbc/bankDataSource"
type="javax.sql.DataSource"
auth="Container"
driverClassName="org.h2.Driver"
url="jdbc:h2://home/zlatan/test.h2;MODE=PostgreSQL"
username="sa"
password="sa"
maxActive="1"
maxIdle="1"
defaultAutoCommit="false"
testOnBorrow="true"
validationQuery="select 1"/>

</Context>


Prva 3 atributa Resource elementa su prepisana iz web.xml fajla. Zatim ide ime drajvera, url, uname, pass kao i kod ručnog pravljenja konekcije na bazu. Zatim se postavlja maksimalni broj konekcija u pool-u i maksimalan broj besposlenih konekcija. Isključuje se autoCommit za konekcije u pool-u. Poslednje 2 opcije uključuju ispitivanje da li je konekcija živa. Ispitivanje se radi pri pribavljanju konekcije iz pool-a a poslednja opcija je upit kojim se testira konekcija.

Postoje mnoge druge opcije koje nisam prikazao a među njima su najkorisnije removeAbandoned sa podešavanjima removeAbandonedTimeOut i logAbandoned, zatim opcija defaultTransactionIsolation i defaultTransactionIsolation.

U kodu se konekcija pribavlja na sledeći način:


Context context = new InitialContext();
DataSource ds = (DataSource) context.lookup(
"java:comp/env/jdbc/bankDataSource");
Connection conn = ds.getConnection();
// jer se u prethodnoj liniji konekcijaproverava pozivom select 1
// pa ako bi posle select 1 pozvali setTransactionIsolation() dobili
// bi gresku da se izolacija ne moze postaviti u sred transakcije
conn.commit();
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
// . . .


Napomena: za više o context.xml pogledati Tomcat dokumentaciju

Iako je ovde predstavljen Tomcatov način za definisanje connection pool-a on se može definisati i na aplikacionim serverima (Glassfish, IBM WebSphere...) no svaki od njih ima drugačiji način za definisanje poolova.

No comments: