Spring AOP - transaction - issue
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schem...ing-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- this is the service object that we want to make transactional -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!--
<bean id="txIntercept" class="org.springframework.transaction.interceptor .TransactionInterceptor"/>
-->
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- ensure that the above transactional advice runs for any execution
of an operation defined by the FooService interface -->
<aop:config proxy-target-class="true">
<aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.*FooService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
</aop:config>
<!-- don't forget the DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbc.JDBCDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost/"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<!-- similarly, don't forget the PlatformTransactionManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSou rceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- other <bean/> definitions here -->
</beans>
package x.y.service;
public interface FooService {
Foo getFoo(String fooName);
Foo getFoo(String fooName, String barName);
void insertFoo(Object obj);
void updateFoo(Foo foo);
}
package x.y.service;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceUtil s;
public class DefaultFooService implements FooService {
public Foo getFoo(String fooName) {
throw new UnsupportedOperationException();
}
public Foo getFoo(String fooName, String barName) {
throw new UnsupportedOperationException();
}
public void insertFoo(Object obj) {
Connection con = null;
PreparedStatement pst = null;
try {
con = DataSourceUtils.getConnection((DataSource)obj);
System.out.println(" con : " + con.hashCode());
//con.createStatement().executeUpdate("create table contacts (name varchar(45),email varchar(45),phone varchar(45))");
pst = con.prepareStatement("insert into contacts values(?,?,?)");
pst.clearParameters();
pst.setString(1, "test");
pst.setString(2, "a@a.com");
pst.setString(3, "9742480004");
int i = pst.executeUpdate();
} catch (Exception e) {
try {
if (con != null) {
con.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
/* if (con != null && !con.isClosed()) {
System.out.println(" finally 1");
con.commit();
con.close();
}
System.out.println("pst " + pst);
if (pst != null && !pst.isClosed()) {
System.out.println(" finally 2");
pst.close();
}*/
//System.out.println("con.isClosed() : " + con.isClosed() + "pst.isClosed() : " + pst.isClosed());
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
}
public void updateFoo(Foo foo) {
throw new UnsupportedOperationException();
}
}
package x.y.service;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlAp plicationContext;
import org.springframework.aop.framework.autoproxy.Defaul tAdvisorAutoProxyCreator;
//import org.springframework.aop.config.;
public final class Boot extends Thread{
private Object ds;
private FooService fs;
private Boot(Object ds, FooService fs){
this.ds = ds;
this.fs = fs;
}
@Override
public void run() {
fs.insertFoo(ds);
}
public static void main(final String[] args) throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext .xml", Boot.class);
FooService fooService = (FooService) ctx.getBean("fooService");
Object dataSource = ctx.getBean("dataSource");
Thread[] ta = new Thread[5];
for (int i = 0; i < ta.length; i++) {
Thread t = new Boot(dataSource, fooService);
t.start();
}
}
}
DEBUG logs
========
2012-10-05 15:15:22,298 [main] DEBUG org.springframework.aop.framework.Cglib2AopProxy - Creating CGLIB2 proxy: target source is SingletonTargetSource for target object [x.y.service.DefaultFooService@1eec35]
2012-10-05 15:15:22,361 [main] DEBUG org.springframework.aop.framework.Cglib2AopProxy - Unable to apply any optimisations to advised method: public void x.y.service.DefaultFooService.insertFoo(java.lang. Object)
2012-10-05 15:15:22,361 [main] DEBUG org.springframework.aop.framework.Cglib2AopProxy - Unable to apply any optimisations to advised method: public x.y.service.Foo x.y.service.DefaultFooService.getFoo(java.lang.Str ing)
2012-10-05 15:15:22,361 [main] DEBUG org.springframework.aop.framework.Cglib2AopProxy - Unable to apply any optimisations to advised method: public x.y.service.Foo x.y.service.DefaultFooService.getFoo(java.lang.Str ing,java.lang.String)
2012-10-05 15:15:22,361 [main] DEBUG org.springframework.aop.framework.Cglib2AopProxy - Unable to apply any optimisations to advised method: public void x.y.service.DefaultFooService.updateFoo(x.y.servic e.Foo)
Please let me know why is this message appears in the debug log