Connection Sharing in GlassFish Application Server
When multiple connections x and y acquired by an application are used within a transaction scope, application server will provide shared connection behavior when the following set of properties are satisfied.
- x and y are collocated in a single Java Virtual Machine process address space.
- x and y are using a single transactional resource manager.
- x and y have identical properties.
- x and y are marked as shareable.
- x and y are used within a container-managed or bean-managed transaction scope.
Ex:
When multiple connection requests to same data-source happen within a transaction, application server may re-use the connection already acquired as a part of the transaction.
Let us consider the following scenario :
Tx Scope Begins get Connection1 do DB operation get Connection2 do DB operation Tx Scope EndsSuppose, connection-2 has to be acquired from the same data-source as that of connection-1, application server may re-use the physical connection of connection-1.
How do I enable/disable Connection Sharing ?
By specifying the following highlighted property in deployment descriptor (web.xml / ejb-jar.xml). Default value is Shareable.
<resource-ref>
<res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
To disable sharing:
<res-sharing-scope>Unshareable</res-sharing-scope>Note : For Local Transactions, only shareable scope is applicable.
Connection Sharing in BMPs
a) Container Managed Transaction:
( <transaction-type>Container</transaction-type>)
BMP-Bean-1
businessMethod(){ // Transaction attribute "Required"
con1 = dataSource.getConnection();
doDBOperation();
bean2 = lookupBean2;
bean2.businessMethod();
con1.close();
}
BMP-Bean-2
businessMethod(){ // Transaction Attribute "Required"
con2 = dataSource.getConnection(); // same data-source as that of con1 in bean-1
doDBOperation();
con2.close();
}
During Bean2's method call, connection sharing happens. Application server first acquires a free connection from the connection pool. During connection enlistment, connection association happens which will map the ManagedConnection (and hence physical connection) of con-1 to con-2. Thus DBOperation happens through same physical connection (connection sharing).
What happens to the actual Physical Connection acquired by conn-2 ?
By the end of transaction, physical connection of con-1 is dissociated from conn-2 and conn-2 is mapped back with its actual physical connection. The purpose of this connection association and dissociation can be seen in the following sample.
b)Bean Managed Transaction (<transaction-type>Bean</transaction-type>)
businessMethod(){
UserTransaction uTx = entityContext.getUserTransaction();
try{
uTx.begin();
con1 = dataSource.getConnection();
doDBOperation() using con1;
con2 = dataSource.getConnection();
doDBOperation() using con2; //using physical connection of conn-1, connection sharing.
uTx.commit();
}
catch(SQLException sqle){
uTx.rollback();
}
con1.close();
doDBOperation() using con2; // using actual physical connection, no sharing involved.
con2.close();
}
After commit/rollback, con2 is associated back with its actual physical connection. Thus during doDBOperation() after the UserTransaction scope, actual physical connection of conn-2 is used.How do I know that connection-sharing has actually happened?
In the sample above, dataSource ( com.sun.appserv.jdbc.DataSource ) has a method to get the physical connection.
To get the physical connection,Connection pc1 = dataSource.getConnection(con1); Connection pc2 = dataSource.getConnection(con2);pc1, pc2 can be retrieved within and outside the scope of a transaction and compared.

- Picture shows connections' state in Application Server, Resource Adapter (Physical Connection), within and outside the transaction scope.
- Log shows the connection objects' hash-code value within and outside the transaction scope.
Few interesting scenarios to see whether connection sharing happens or not is,
a) con1 = dataSource.getConnection(); UserTransaction uTx = entityContext.getUserTransaction(); uTx.begin(); con2 = dataSource.getConnection(); doDBOperation() using connection-1 doDBOperation() using connection-2 uTx.commit(); con1.close(); con2.close(); b) con1 = dataSource.getConnection(); con2 = dataSource.getConnection(); UserTransaction uTx = entityContext.getUserTransaction(); uTx.begin(); doDBOperation() using connection-1 doDBOperation() using connection-2 uTx.commit(); con1.close(); con2.close();
Are there any restrictions when connections are used in sharing scope?
Yes, When connection sharing is enabled, certain properties should not be modified. Suppose connection-1's property is changed and when sharing happens, connection-2 will have the modified property. Application Server will throw SharingViolationException. More details can be found in the J2EE Connector Architecture 1.5 Specification, section 7.9 - Transaction Management > Connection Sharing.
Technorati Tags:
glassfish
Posted by Premkumar on June 02, 2006 at 03:00 PM IST #
Hi,
I performed your example and see in the log file that I use only 1 phisycal connection.
But when I use admin console Monitor Resources for the same java code example I see that NumConnUsed equals to 2 and NumConnFree equals to total_connection_in_the_pool -2 .
Please how can I see real number of NumConnFree and NumConnUsed.
Thank you
Irena
Posted by irenagarber@yahoo.com on January 08, 2008 at 07:44 PM IST #
Hi,
I performed your example and see in the log file that I use only 1 phisycal connection.
But when I use admin console Monitor Resources for the same java code example I see that NumConnUsed equals to 2 and NumConnFree equals to total_connection_in_the_pool -2 .
Please how can I see real number of NumConnFree and NumConnUsed.
Thank you,
Irena
Posted by Irena Garber on January 08, 2008 at 07:47 PM IST #