Beings I seem to be temporarially unable to upload a file (brain is a
little fried), I have included it below.
I am not sure by any means that I have it correct. I looked at the
example you provided, but what I am really hoping to get done is to
use the annotations. @Transactional, and let the proxied service beans
contain the information so that I don't have to manage a xml file.
My overall intent is to use a small test app (which I can bundle if
needed) to get an good understanding of how the Tx's work and then
replace the EJB layer in my main app with Spring. I am still at a
point where I can replace them all (we are almost to testing) so I
don't have to manage two different connection pools, etc, while doing
a piece-meal conversion.
But that's not an option when the Tx management doesn't work.
My app that I am testing with looks like this.
I have struts and a single action. It does nothing other than call
into a business service class to update a dummy record in the DB.
Home Action
WebApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext(super.servlet.getServletContext());
FooServiceImpl foo = (FooServiceImpl)context.getBean("fooService");
System.out.println("The FooService class is : " +
foo.getClass().getCanonicalName());
foo.insertId(id);
System.out.println("Tried to insert id " + id);
id++;
int foundId = foo.getId();
System.out.println("The update completed successfully");
System.out.println("The returned id was : " + foundId);
FooService - Creates DAO, calls update method, returns ID found.
@Transactional
public class FooServiceImpl {
private static FooServiceImpl service = null;
public static FooServiceImpl getInstance(){
if (service == null){
service = new FooServiceImpl();
}
return service;
}
private FooServiceImpl(){
}
@Transactional(propagation=Propagation.REQUIRED)
public int insertId(int ID) {
TestDAO dao = new TestDAO();
dao.insertId(ID);
return dao.getId();
}
@Transactional(propagation=Propagation.SUPPORTS)
public int getId(){
TestDAO dao = new TestDAO();
return dao.getId();
}
}
TestDAO - Exeucte the SQL. Gets it's DataSource from the StaticConn
Manager class which looks up the DS using SpringBean call.
public class TestDAO {
public void insertId(int id){
String SQL = "insert into test (id, action_date) values (?,
current_timestamp);";
Connection conn = null;
try {
conn = ConnManager.getConnection("springDataSource");
PreparedStatement ps = conn.prepareStatement(SQL);
ps.setInt(1, id);
ps.execute();
} catch (SQLException e){
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e){
}
}
}
public int getId(){
String SQL = "select * from test order by action_date desc";
Connection conn = null;
int id = 0;
try {
conn = ConnManager.getConnection("springDataSource");
PreparedStatement ps = conn.prepareStatement(SQL);
ResultSet rs = ps.executeQuery();
if (rs.next()){
id = rs.getInt("id");
}
} catch (SQLException e){
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e){
}
}
return id;
}
ConnManager - Looks up DS from Spring config.
public class ConnManager {
private static Hashtable<String, DataSource> dsTable = new
Hashtable<String, DataSource>();
static Connection getConnection(String name){
Connection conn = null;
DataSource ds = null;
name = "springDataSource";
try {
if (dsTable.containsKey(name)){
conn = DataSourceUtils.doGetConnection(dsTable.get(name));
} else {
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
ds = (DataSource)context.getBean(name);
conn = DataSourceUtils.doGetConnection(ds);
}
//conn.setAutoCommit(false);
System.out.println("The connection is transactional " +
DataSourceUtils.isConnectionTransactional(conn, ds));
} catch (SQLException e){
e.printStackTrace();
}
return conn;
}
}
applicationContext.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:tx="
http://www.springframework.org/schema/tx"
xmlns:aop="
http://www.springframework.org/schema/aop"
xmlns:jee="
http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
">
<tx:annotation-driven transaction-manager="txManager" proxy-target-
class="true" />
<bean id="springDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="java:jdbc/SpringDB" />
<property name="lookupOnStartup" value="true" />
<property name="cache" value="true" />
<property name="proxyInterface" value="javax.sql.DataSource" />
</bean>
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager" />
<!--
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="springDataSource"/>
</bean>
-->
<bean id="fooService" class="foo.FooServiceImpl">
</bean>
<bean id="fooBaseTransactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="target">
<ref bean="fooService" />
</property>
<property name="transactionManager">
<ref bean="txManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">
PROPAGATION_NEVER,ISOLATION_READ_UNCOMMITTED,-java.lang.Exception
</prop>
</props>
</property>
</bean>
</beans>
If later I can figure out how to add these as files, I will.
Thanks for the help so far.