9.spring:事务管理(下):声明式事务管理
声明式事务管理
sprin的声明式事务是管理AOP技术实现的事务管理,其本质是是对方法前后进行拦截,然后
在目标方法开始之前创建或者加入一个事务,在执行完成目标方法之后根据执行情况提交或者回滚事务。
声明式事务管理优点:不需要通过编程的方式管理事务,因而不需要在业务逻辑代码中掺杂事务处理的代码,
只需相关的事务规则声明便可以将事务规则应用到业务逻辑中。
在开发中使用声明式事务处理不仅因为其简单,更主要是这样可以使纯业务代码不被污染,方便后期的维护。
声明式事务管理不足之处:是最细粒纯度只能作用到方法级别,无法做到像编程事务管理那样作用到代码块级别。
spring的声明式事务管理可以通过两种方式实现:1、xml配置方式 2、使用@Transactionl注解方式
1).xml配置方式
public interface TestDao { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Repository("TestDao") public class TestDaoImpl implements TestDao{ @Autowired private JdbcTemplate jdbcTemplate ; @Override public int save(String sql, Object[] p) { return jdbcTemplate.update(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return jdbcTemplate.update(sql, p); } }
public interface TestService { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Service("TestService") public class TestServiceImpl implements TestService{ @Autowired private TestDao testDao ; @Override public int save(String sql, Object[] p) { return testDao.save(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return testDao.delete(sql, p); } }
spring配置文件
<!--扫描指定的包--> <context:component-scan base-package="com.MrChegnse.jdbctest"></context:component-scan> <!-- 配置数据源 --> <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <!-- 配置jdbc模块 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 为数据源添加事物管理 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 编写声明式事物 --> <!-- transaction-manager:DataSourceTransactionManager类的实例化 --> <tx:advice id="myAdvice" transaction-manager="dataSourceTransactionManager"> <tx:attributes>
<!-- * 表示任意的方法 --> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 编写AOP让spring自动对目标生成代理 --> <aop:config> <!-- 定义切点 --> <aop:pointcut expression="execution(* com.MrChegnse.jdbctest.*.*())" id="point"/> <!-- 切面:将切入点与通知关联 --> <aop:advisor advice-ref="myAdvice" pointcut-ref="point"/> </aop:config>
测试
public ApplicationContext getapp(){ return new ClassPathXmlApplicationContext("tx.xml"); }
public String test11(){
TestService testService = (TestService) getapp().getBean("testService");
String msg2 = "";
Object a [] = {2,"user2","pwd2"};
String sql = "insert into user values(?,?,?)";
try {
testService.save(sql, a);
} catch (Exception e) {
msg2 ="error";
e.printStackTrace();
}
return msg2;
}
@Test
public void test22(){
String a = test11();
System.out.println(a);
}
注:
1、<tx:advice>配置事务的通知
2、<tx:advice>一般需要指定id和transaction-manager属性,id是在配置文件中唯一标识,transaction-manager指定事务管理器
3、<tx:attributes>是<tx:advice>的子元素、执行执行事务的细节
4、<tx:advice>配置了事务增强处理后就可通过AOP配置让spring自动对目标生成代理
5、<aop:pointcut expression="execution(* com.MrChegnse.jdbctest.*.*())" id="point"/>
*:代表任意类型、任意类、任意方法
6、<aop:advisor advice-ref="myAdvice" pointcut-ref="point"/>:将切入点与通知关联
2)@Transactionl注解声明式事务管理
public interface TestDao { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Repository("TestDao") public class TestDaoImpl implements TestDao{ @Autowired private JdbcTemplate jdbcTemplate ; @Override public int save(String sql, Object[] p) { return jdbcTemplate.update(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return jdbcTemplate.update(sql, p); } }
public interface TestService { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Service("TestService") @Transactional public class TestServiceImpl implements TestService{ @Autowired private TestDao testDao ; @Override public int save(String sql, Object[] p) { return testDao.save(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return testDao.delete(sql, p); } }
spring的配置文件
<context:component-scan base-package="com.MrChegnse.jdbctest"></context:component-scan> <!-- 配置数据源 --> <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <!-- 配置jdbc模块 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 为数据源添加事物管理 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 为事务管理器注册注解驱动 --> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
测试
public String test11(){ TestService testService = (TestService) getapp().getBean("testService"); String msg2 = ""; Object a [] = {2,"user2","pwd2"}; String sql = "insert into user values(?,?,?)"; try { testService.save(sql, a); } catch (Exception e) { msg2 ="error"; e.printStackTrace(); } return msg2; } @Test public void test22(){ String a = test11(); System.out.println(a); }
注:
1、@Transactional:可以作用于接口、接口方法、类以及类的方法
2、当作用于类上时,该类的所有public方法都将具有该类型的事务属性,同时也可以在方法级别使用该注解来覆盖类级别的定义
3、Spring小组建议不要在接口或者方法上使用该注解,因为他只有在使用基于接口的代理时才会生效。
4、@Transactional(rollbackFor=RuntimeException.class):不对RuntimeException回滚生效
5、@Transactional(rollbackFor=Exception.class):不对Exception回滚生效
6、<tx:annotation-driven />:为事务管理器注册注解驱动驱动器
7、 @Transactional
public class TestServiceImpl implements TestService{
加上注解就可以指定这个类需要接受Spring的事务管理
只能针对public属性范围内的方法添加
基本完结..........