请教一个关于spring事务的问题 ?


由于问题较长,希望各位高手能够耐心看完,谢谢, 数据库mysql.

CREATE TABLE CUSTOMERS (
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NOT NULL,
sex VARCHAR(45) NOT NULL,
age INTEGER NOT NULL,
PRIMARY KEY(id)
)
ENGINE = InnoDB;

所有jdbc实现的dao基类


public class DAO {
DataSource dataSource;
public void setDataSource(DataSource dataSource)
throws DataAccessException {
this.dataSource = dataSource;
}
}

ICustomerDAO接口


public interface ICustomerDAO {
Long insertCustomer(Customer customer)throws DataAccessException;
}

ICustomerDAO接口的实现类CustomerDAO_Imp继承DAO实现ICustomerDAO


public class CustomerDAO_Imp extends DAO implements ICustomerDAO {

public Long insertCustomer(Customer customer) throws DataAccessException {
Long result = null;
Connection conn = null;
try {
conn = dataSource.getConnection();
String sql = "INSERT INTO CUSTOMERS(name,sex,age)values(?,?,?);";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, customer.getName());
pstmt.setString(2, customer.getSex());
pstmt.setInt(3, customer.getAge());
pstmt.execute();
pstmt.close();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select max(id) from CUSTOMERS ;");
rs.next();
result = new Long(rs.getLong(1));
rs.close();
stmt.close();
return result;
} catch (SQLException e) {
e.printStackTrace();
throw new DataAccessException(e.getMessage());
} finally {
try {
conn.close();
} catch (SQLException e1) {
e1.printStackTrace();
throw new DataAccessException(e1.getMessage());
}
}
}

服务接口

public interface IService {
void method1();
}

IService服务接口实现类Service_Imp
public class Service_Imp implements IService {

ICustomerDAO customerDAO;
public void setCustomerDAO(ICustomerDAO customerDAO) {
this.customerDAO = customerDAO;
}

public void method1() { //fail
Customer customer = new Customer();
customer.setName("Jim");
customer.setSex("Male");
customer.setAge(24);
Long cid = customerDAO.insertCustomer(customer);
Order order = new Order();

System.out.println(
"customers table should not contains customer with id " + cid);

int i = 1 / 0; //exception in service method

}
配置文件


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>org.gjt.mm.mysql.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/test</value>
</property>
<property name="username"><value>root</value></property>
<property name="password"><value>root</value></property>
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>

<bean id="customerDAO" class="dao.imp.jdbc.CustomerDAO_Imp">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>

<bean id="serviceImp"
class="service.imp.Service_Imp">
<property name="customerDAO">
<ref local="customerDAO" />
</property>
</bean>

<bean id="service"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="serviceImp" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>

测试过程


public class testTransaction {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
IService service = (IService) context.getBean("service");
int testMethod = 1;
switch (testMethod) {
case 1 :
service.method1();
break;
case 2 :


输出

customers table should not contains customer with id 1
java.lang.ArithmeticException: / by zero
at service.imp.Service_Imp.method1(Service_Imp.java:32)

问题:
在service.method1();中出现了/ by zero异常,这个方法在事务中
为什么数据库中有customer with id 1 没有回滚 ??
我错在哪里了?请各位解释一下spring管理事务过程好么?

问题解决了

结果就是两行行代码的问题

使用spring管理DataSource事务管理,需要采用一个特定的编码规范。需要以一个特殊的方式获得连接资源或者会话资源,允许相关的 PlatformTransactionManager实现跟踪连接的使用,并且当需要时应用事务管理。
不应该调用一个数据源的 getConnection()方法和Connection的close()方法,而必须使用Spring的 org.springframework.jdbc.datasource.DataSourceUtils类,如下:
Connection conn = DataSourceUtils.getConnection(dataSource);
.......................
DataSourceUtils.releaseConnection(conn, dataSource);

我就是调用了Connection conn = dataSource.getConnection();
................................
conn.close();
结果郁闷了两天,一行代码一天