尝试了下Spring的Declarative Transaction, 但是没成功回滚事务, 下面是我的配置和代码,向各位高手请教:配置:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL">
<value>jdbc:oracle:thin:system/[email protected]:1521/dbPool</value>
</property>
</bean> <bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean> <bean id="UserServiceTransactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>

<property name="target">
<bean class="UserService">
<property name="dao">
<ref bean="userDAO" />
</property>
</bean>
</property>

<property name="transactionAttributes">
<props>
<prop key="doTransaction*">PROPAGATION_REQUIRED</prop>
<prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean> <bean id="user" class="User">
<property name="info">
<value>"This is the commmon information"</value>
</property>
</bean> <bean id="userService" class="UserService">
<property name="dao">
<ref bean="userDAO" />
</property>
</bean> <bean id="userDAO" class="UserDAO">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate" />
</property>
</bean>

</beans>
代码:
// SERVICE
import java.util.*;import org.springframework.dao.TransientDataAccessResourceException;public class UserService {

private UserDAO dao; public UserDAO getDao()
{
return dao;
} public void setDao(UserDAO dao)
{
this.dao = dao;
}

public void doTransaction()
{
List<User> users = new ArrayList<User>();
for(int i = 0; i < 10; i++) {
User user = new User();
user.setName("User " + i);
users.add(user);
}
this.dao.insertUsers("test", users);               // 这里抛出一个Unchecked Exception, 想让doTransaction之前执行的insert操作也回滚,但是没有成功~~~
if(1 == 1)
throw new TransientDataAccessResourceException("EEE");
this.dao.insertUsers("test2", users);
}

}// DAO
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import org.springframework.jdbc.core.*;public class UserDAO { private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate()
{
return jdbcTemplate;
} public void setJdbcTemplate(JdbcTemplate jdbcTemplate)
{
this.jdbcTemplate = jdbcTemplate;
} public void insertUsers(String tableName, final List<User> users)
{
this.jdbcTemplate.batchUpdate("insert into system." + tableName + "(column1, column2, column3) values(system.TEST_SEQUENCE.nextval, ?, ?)",
new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws SQLException
{
User user = users.get(i);
ps.setString(1, user.getName());
ps.setString(2, user.getInfo());
}

// indicate inpute size of batch  
public int getBatchSize()
{
return  users.size();
}
});
}

}

解决方案 »

  1.   

    要定义一个拦截器把
    <bean id="transactionInterceptor"
    class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager" ref="transactionManager" />
    <!-- 配置事务属性 以save upadte……等开头得方法 -->
    <property name="transactionAttributes">
    <props>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="add*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="mod*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="set*">PROPAGATION_REQUIRED</prop>
    <prop key="change*">PROPAGATION_REQUIRED</prop>
    <prop key="get*">readOnly</prop>
    <prop key="*">readOnly</prop>
    </props>
    </property>
    </bean> <!-- 自动事务代理 -->
    <bean
    class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <!-- service层的指定为代理 -->
    <property name="beanNames" value="*Service" />
    <property name="proxyTargetClass" value="true" />
    <property name="interceptorNames" value="transactionInterceptor" />
    </bean>
      

  2.   

    没有指定哪些方法参与事物
     <!-- 自动事务代理 -->  <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  <!-- service层的指定为代理 -->  <property name="beanNames" value="*Service" />  <property name="proxyTargetClass" value="true" />  <property name="interceptorNames" value="transactionInterceptor" />  </bean>这个正解
      

  3.   


    我没有使用BeanNameAutoProxyCreator,而是用基本的TransactionProxyFactoryBean,方法拦截我也写在配置里面了:
    <property name="transactionAttributes">
    <props>
    <prop key="doTransaction*">PROPAGATION_REQUIRED</prop>
    <prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>
    </props>
    </property>
    </bean>应该不是这个原因吧
      

  4.   

    忘了说一点:我用的是spring 2.5.6