参考:
事务的概念
spring中的事务管控
spring并不直接管理事务,而是提供了多种事务管理器,将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
spring的事务管理接口是org.springframework.transaction.PlatformTransactionManager
,通过这个接口,spring为各个平台如jdbc,hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
spring默认checked异常(error,runtime异常)回滚,非checked异常不会回滚。
举个小栗子:
目录结构如下:
事务配置文件如下:
<?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:context="http://www.springframework.org/schema/context"
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/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="zz" class="com.zz.ioc.ZZ"></bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>
<bean id="dbDao" class="com.zz.dao.impl.DBDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<aop:config>
<aop:pointcut id="daoOperation" expression="execution(* com.zz.dao..*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="daoOperation"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
</beans>
操作数据库的dao层代码如下:
package com.zz.dao;
public interface DBDao {
public void update(int id);
public void query(int id);
}
package com.zz.dao.impl;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import com.zz.dao.DBDao;
public class DBDaoImpl implements DBDao {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void update(int id) {
String sql = "update myt set num=num+1 where id = ?";
int i = this.jdbcTemplate.update(sql, id);
System.out.println(i);
throw new UnsupportedOperationException();
}
public void query(int id) {
String sql = "select num from myt where id = ?";
int num = jdbcTemplate.queryForObject(sql, Integer.class, id);
System.out.println(num);
throw new UnsupportedOperationException();
}
}
测试代码如下:
package com.zz.springDemo;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zz.dao.DBDao;
public class TransactionTest {
private static AbstractApplicationContext applicationContext = null;
@BeforeClass
public static void init() {
applicationContext = new ClassPathXmlApplicationContext("myaop.xml", "myspring.xml");
}
@AfterClass
public static void destory() {
applicationContext.close();
}
@Test
public void dao() {
DBDao dbDao = (DBDao) applicationContext.getBean("dbDao");
dbDao.update(1);
}
}
测试结果如下:
执行前后id为1的那条数据都没有变化。
如果不用事务管理,尽管最后会抛出异常,但数据仍然会+1。