• 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>一般需要指定idtransaction-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属性范围内的方法添加

    基本完结..........

  • 相关阅读:
    minimum-path-sum
    pascals-triangle
    Java -- 二分查找
    redis缓存雪崩,击穿,穿透(copy)
    使用redis限制提交次数
    数据库的悲观锁和乐观锁
    mysql常用命令
    php压缩Zip文件和文件打包下载
    php去除数据库的数据空格
    php获取本年、本月、本周时间戳和日期格式的实例代码(分析)
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10100116.html
Copyright © 2020-2023  润新知