spring框架 AOP基于AspectJ注解方式的开发 and spring的JDBC模板的使用and spring的事务管理

spring基于AspectJ方式的注解开发

开发实例

引入jar包

在这里插入图片描述

引入applicationContext.xml配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--将增强类交给spring管理-->
    <bean id="user" class="com.dao.impl.UserDaoImpl"></bean>
    <!--将切面类交给spring管理-->
    <bean id="myAspectAnno" class="com.domain.MyAspectAnno"></bean>

    <!--使用基于AspectJ方式的注解方式的开发-->
    <!--在配置文件中开启注解方式的开发-->
    <aop:aspectj-autoproxy />
</beans>

创建要增强的User.java类,并在配置文件中配置

在这里插入图片描述

public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("保存用户!!");
    }

    @Override
    public String find() {
        System.out.println("查找用户");
        return "哈哈哈";
    }

    @Override
    public void delete() {
        int a;
        a=2/0;
        System.out.println("删除用户");
    }

    @Override
    public void update() {
        System.out.println("更新用户");
    }
}

创建切面类,并在配置文件中配置,在切面类中使用AOP注解

在这里插入图片描述

package com.domain;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import java.beans.Transient;

@Aspect
public class MyAspectAnno  {

    //前置通知
    @Before(value = "execution(* com.dao.impl.UserDaoImpl.save(..))")
    public void demo(){
        System.out.println("权限校验");
    }

    //后置通知
//    @AfterReturning(value = "execution(* com.dao.impl.UserDaoImpl.find(..))" ,returning = "result")
    @AfterReturning(value = "MyAspectAnno.pointcut1()" , returning = "result")
    public void demo2(Object result ){
        System.out.println("保存日志");
        System.out.println(result);
    }

    //环绕通知
    @Around(value = "execution(* com.dao.impl.UserDaoImpl.update(..))")
    public Object demo3(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("权限校验");
        //运行原方法
        Object o = joinPoint.proceed();
        System.out.println("保存日志");
        return o;
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.dao.impl.UserDaoImpl.delete(..))", throwing = "throwable")
    public void demo4(Throwable throwable)  {
        System.out.println("异常通知======"+throwable.getMessage());
    }

    //最终通知
//    @After(value = "execution(* com.dao.impl.UserDaoImpl.find(..))")
    @After(value = "MyAspectAnno.pointcut1()")
    public void demo5(){
        System.out.println("最终都要执行");
    }

    //切入点注解
    @Pointcut(value = "execution(* com.dao.impl.UserDaoImpl.find(..))")
    private void pointcut1(){}
}

运行实例

在这里插入图片描述

通知类型

  • 前置通知
 //前置通知
    @Before(value = "execution(* com.dao.impl.UserDaoImpl.save(..))")
    public void demo(){
        System.out.println("权限校验");
    }


  • 后置通知
   //后置通知
//    @AfterReturning(value = "execution(* com.dao.impl.UserDaoImpl.find(..))" ,returning = "result")
    @AfterReturning(value = "MyAspectAnno.pointcut1()" , returning = "result")
    public void demo2(Object result ){
        System.out.println("保存日志");
        System.out.println(result);
    }
  • 环绕通知
//环绕通知
    @Around(value = "execution(* com.dao.impl.UserDaoImpl.update(..))")
    public Object demo3(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("权限校验");
        //运行原方法
        Object o = joinPoint.proceed();
        System.out.println("保存日志");
        return o;
    }
  • 异常通知
//异常通知
    @AfterThrowing(value = "execution(* com.dao.impl.UserDaoImpl.delete(..))", throwing = "throwable")
    public void demo4(Throwable throwable)  {
        System.out.println("异常通知======"+throwable.getMessage());
    }
  • 最终通知
//最终通知
//    @After(value = "execution(* com.dao.impl.UserDaoImpl.find(..))")
    @After(value = "MyAspectAnno.pointcut1()")
    public void demo5(){
        System.out.println("最终都要执行");
    }
  • 切入点注解

当通知的某一个类型方法在多处都要增强,如果万一以后修改某个方法,那比较麻烦,所以出现了切入点的注解

//切入点注解
    @Pointcut(value = "execution(* com.dao.impl.UserDaoImpl.find(..))")
    private void pointcut1(){}
======================================================
  //最终通知
//    @After(value = "execution(* com.dao.impl.UserDaoImpl.find(..))")
    @After(value = "MyAspectAnno.pointcut1()")
    public void demo5(){
        System.out.println("最终都要执行");
    }
       //后置通知
//    @AfterReturning(value = "execution(* com.dao.impl.UserDaoImpl.find(..))" ,returning = "result")
    @AfterReturning(value = "MyAspectAnno.pointcut1()" , returning = "result")
    public void demo2(Object result ){
        System.out.println("保存日志");
        System.out.println(result);
    }

spring的JDBC模板的使用

spring框架是一站式框架,提供了每一层的解决方案。
在持久层的决绝方案是:ORM模块和JDBC模板
在这里插入图片描述

spring JDBC模板的使用

  1. 要想使用JDBC模板,必须导入相关的jar包

连接数据库的jar包:mysql-connector-java-5.1.39-bin.jar
spring框架中JDBC模板的jar包:
spring-jdbc-4.2.4.RELEASE.jar
spring-tx-4.2.4.RELEASE.jar

  1. JDBC模板的使用,代码实现

注意:1. 使用的是spring框架自带的连接池,也可以使用第三方开源的连接池:c3p0等。
2. spring的JDBC模板是用来简化数据库的CRUD操作的,类似于DBUtils工具类。连接数据库还是得依赖于连接池。

	@Test
    public void demo(){
        //使用spring自带的数据库连接池
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/hou");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");

        //创建spring的jdbc模板,类似于DbUtils,主要作用是简化了CRUD 的操作
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.update("insert into account values (null,?,?)","张三",1000d);
    }

将数据库连接池和JDBC模板交给spring管理

将数据库连接池交给spring管理,其中要给属性赋值,有两种办法

  1. 直接赋值响应的加载器,url,数据库用户名,数据库密码
  2. 使用配置文件,将加载器,url 等写在配置文件中,在applicationContext.xml中加载配置文件。
	<!--引入配置文件-->
    <!--第一种方法:推荐-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--第二种方法:不推荐-->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties"></property>
    </bean>

    <!--将spring的数据库连接池交给spring管理-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/hou"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <!--使用配置文件jdbc.properties,推荐使用-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!--将spring的JDBC模板交给spring管理-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class springDemo2 {

    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Test
    public void demo2(){
        jdbcTemplate.update("insert into account values (null,?,?)","王五33",1000d);
    }
}

使用c3p0开源连接池

  • 引入相关jar包

进入spring框架中整理好了的相关的c3p0的jar包,不需要去下载官网的单纯的c3p0jar包
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

  • 将连接池交给spring管理
 <!--使用c3p0开源连接池,并将其交给spring管理-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hou"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

    <!--将spring的JDBC模板交给spring管理-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

使用dbcp开源连接池

  • 引入相关jar包

进入spring框架中整理好了的相关的c3p0的jar包,不需要去下载官网的单纯的c3p0jar包
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

  • 将连接池交给spring管理
 <!--使用dbcp开源连接池,并将其交给spring管理-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/hou"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

    <!--将spring的JDBC模板交给spring管理-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

使用spring的JDBC模板实现数据库的CRUD操作

  • 增加操作
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class springDemo2 {

    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Test
    public void demo2(){
        jdbcTemplate.update("insert into account values (null,?,?)","王五33",1000d);
    }
}
  • 删除操作
@Test
    public void demo4(){
        jdbcTemplate.update("delete from account where id = ?",1);
    }
  • 修改操作
  @Test
    public void demo3(){
        jdbcTemplate.update("update account set name = ?,money = ? where id = ?","哈哈哈",2000d,2);
    }
  • 查询操作

将数据封装到对象中去

  1. 封装到一个对象中去
    使用jdbcTemplate.queryForObject();返回一个对象
  2. 封装到list集合中去
    使用jdbcTemplate.query();返回List集合
  注意:spring提供的JDBC模板需要自己封装对象,不与DbUtils一样,有自己的实现
    > 类,这里只是提供一个接口,自己去实现。
 @Test
    //查询操作
    public void demo5(){
        //普通查询单个属性
        String name = jdbcTemplate.queryForObject("select name from account where id = ?", String.class, 2);
        System.out.println(name);

        //统计查询
        Long aLong = jdbcTemplate.queryForObject("select count(*) from account", Long.class);
        System.out.println(aLong.intValue());

        //将查询到的数据封装到对象中去,spring提供的JDBC模板必须要自己去封装数据
        //封装到一个对象中去
        Object o = jdbcTemplate.queryForObject("select * from account where id = ?", new RowMapper<Object>() {

            @Override
            /*
             * resultSet:返回的是结果集,
             * i:表示的是行号,遍历到第几行了,当返回的是多个对象的时候,这个方法相当于遍历,每一行都会执行一次这个方法
             * */
            public Object mapRow(ResultSet resultSet, int i) throws SQLException {
                Account account = new Account();
                account.setId(resultSet.getInt("id"));
                account.setName(resultSet.getString("name"));
                account.setMoney(resultSet.getDouble("money"));
                return account;
            }
        }, 2);
        System.out.println(o);

        //将多个数据封装到集合中
        List<Account> list = jdbcTemplate.query("select * from account", new RowMapper<Account>() {
            @Override
            //注意:查询多个数据,将其封装到多个对象中,并将对象封装到一个集合中
            //实现数据的封装只是当前行的数据,它会遍历每一行,从而达到每一行的数据都在一个对象中
            public Account mapRow(ResultSet resultSet, int i) throws SQLException {
                Account account = new Account();
                account.setId(resultSet.getInt("id"));
                account.setName(resultSet.getString("name"));
                account.setMoney(resultSet.getDouble("money"));
                return account;
            }
        });
        System.out.println(list.size());
    }

spring的事务的管理

spring的事务管理的API

spring进行事物管理的时候,首先根据平台事物管理器根据事物的定义信息(事物的属性)进行事物的管理,事物管理的过程中产生的事物的状态,保存到事物状态对象中去。

  • 平台事物管理器:PlatFormTransactionManager

平台事物管理器,其实是一个接口,是spring真正管理事物的对象,实现类有:

  1. DataSourceTransactionManager:底层使用的是JDBC模板管理事物的
  2. HibernateTransactionManager:底层使用的是Hibernate管理事物的
  • 事物定义信息:TransactionDefinition

定义事物的信息:也就是事物的属性,有五个属性
传播行为、隔离级别、是否可读、回滚规则,事物超时

  • 事物的状态:TransactionStatus

事务状态:用于记录在事务管理过程中,事务的状态的对象

spring事务的传播行为

Spring中提供了七种事务的传播行为:

  1. 保证多个操作在同一个事务中
    PROPAGATION_REQUIRED :默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来
    PROPAGATION_SUPPORTS :支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
    PROPAGATION_MANDATORY :如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。

  2. 保证多个操作不在同一个事务中
    PROPAGATION_REQUIRES_NEW :如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作
    PROPAGATION_NOT_SUPPORTED :如果A中有事务,将A的事务挂起。不使用事务管理。
    PROPAGATION_NEVER :如果A中有事务,报异常。

  3. 嵌套式事务
    PROPAGATION_NESTED :嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。

spring事务的管理

银行转账的环境搭建

1.使用事物管理器,需要到入jar包

spring-tx-4.2.4.RELEASE.ja

  1. 创建service层和dao层
    service层
package com.service;

public interface AccountService {
    public void trans(String from,String to,double money);
    public void trans3(String from,String to,double money);
}
=================================================================
@Transactional(propagation = Propagation.REQUIRED ,readOnly = false)
public class AccountServiceImpl implements AccountService {
    @Resource(name = "accountDao")
    private AccountDao accountDao;


    public void trans(String from, String to, double money) {
        accountDao.outMoney(from,money);
        int a = 2/0;
        accountDao.inMoney(to,money);
    }

    //如果这个方法不使用事物
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void trans2(String from, String to, double money) {
        accountDao.outMoney(from,money);
        int a = 2/0;
        accountDao.inMoney(to,money);
    }

    @Resource(name = "transactionTemplate")
    private TransactionTemplate transactionTemplate;

    //使用自己编写代码的方式管理事物
    public void trans3(String from, String to, double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.outMoney(from,money);
                int a = 2/0;
                accountDao.inMoney(to,money);
            }
        });
        
    }
}

dao层

为什么dao层实现类继承JdbcDaoSupport类,因为为了简化xml的配置,
向这个dao层的实现类注入数据库连接池,就会自动给你创建JdbcTemplate对象,
所以就不用再配置文件中注入JdbcTemplate对象了。
public interface AccountDao {
    //转出
    public void outMoney(String from, double money);
    //转入
    public void inMoney(String to,double money);
    public void aVoid();
}
====================================================
public class AccountDaoImp extends JdbcDaoSupport implements AccountDao {
    @Override
    public void outMoney(String from, double money) {
        JdbcTemplate jdbcTemplate = this.getJdbcTemplate();
        jdbcTemplate.update("update account set money = money - ? where name = ?",money,from);
    }

    @Override
    public void inMoney(String to,double money) {
        JdbcTemplate jdbcTemplate = this.getJdbcTemplate();
        jdbcTemplate.update("update account set money = money + ? where name = ?",money,to);
    }
    public void aVoid(){
        System.out.println("dadsadsa");
    }
}

  1. 测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:tx3.xml")
public class SpringDemo3 {
    @Resource(name = "accountService")
    private AccountService accountService;

    @Test
    public void demo(){
        accountService.trans("哈哈哈","王五",100d);
    }
    @Test
    public void demo2(){
        accountService.trans3("哈哈哈","王五",100d);
    }

}

编程式的事务管理(自己写代码)

第一步:配置平台事务管理器

<!--&lt;!&ndash;配置事物平台管理器&ndash;&gt;-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

第二步:Spring提供了事务管理的模板类
配置事务的管理的模板类


    <!--配置事物的管理模板,使得事物管理更加的简单-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <!--注入事物平台管理器-->
        <property name="transactionManager" ref="dataSourceTransactionManager"></property>
    </bean>

第三步:在业务层注入事务管理的模板
使用注解方式注入,开启注解

  <context:annotation-config></context:annotation-config>
 @Resource(name = "transactionTemplate")
    private TransactionTemplate transactionTemplate;

第四步:编写事务管理的代码,在service层

 //使用自己编写代码的方式管理事物
    public void trans3(String from, String to, double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.outMoney(from,money);
                int a = 2/0;
                accountDao.inMoney(to,money);
            }
        });
        
    }

声明式的事务管理–实质是AOP

xml方式声明的事务管理

在事物定义的规则中的name属性,是其规则,规定类中的某个具体的方法采用这个事务规则,相当于切面类。

<?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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:annotation-config></context:annotation-config>

    <!--&lt;!&ndash;引入配置文件&ndash;&gt;-->
    <!--&lt;!&ndash;第一种方法:推荐&ndash;&gt;-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--&lt;!&ndash;使用c3p0开源连接池,并将其交给spring管理&ndash;&gt;-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hou"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <bean id="accountService" class="com.service.impl.AccountServiceImpl">
    </bean>

    <bean id="accountDao" class="com.dao.impl.AccountDaoImp">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--&lt;!&ndash;配置事物平台管理器&ndash;&gt;-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事物的增强,相当于aop的切面类>-->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <!--事物管理的规则-->
        <tx:attributes>
        <!--name属性其实是规则,要与aop中的expression属性区分,name属性其实是规定要使用该规则的类中具体哪个方法
            expression属性定位到目标类
            -->
            <tx:method name="*" read-only="false" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!--&lt;!&ndash;AOP的配置&ndash;&gt;-->
    <aop:config>
        <aop:pointcut id="pointcut1" expression="execution(* com.service.impl.AccountServiceImpl.trans(..))"></aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"></aop:advisor>
    </aop:config>


</beans>

具体步骤实现
在这里插入图片描述

注解方式的声明的事物管理

<?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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:annotation-config></context:annotation-config>

    <!--&lt;!&ndash;引入配置文件&ndash;&gt;-->
    <!--&lt;!&ndash;第一种方法:推荐&ndash;&gt;-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--&lt;!&ndash;使用c3p0开源连接池,并将其交给spring管理&ndash;&gt;-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hou"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <bean id="accountService" class="com.service.impl.AccountServiceImpl">
    </bean>

    <bean id="accountDao" class="com.dao.impl.AccountDaoImp">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--&lt;!&ndash;配置事物平台管理器&ndash;&gt;-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--使用注解的方式,开启注解事物-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>


</beans>

具体实现过程
在这里插入图片描述
目标类中要使用注解
在这里插入图片描述
如果想某个方法不使用事物

@Transactional(propagation = Propagation.REQUIRED ,readOnly = false)
public class AccountServiceImpl implements AccountService {
    @Resource(name = "accountDao")
    private AccountDao accountDao;


    public void trans(String from, String to, double money) {
        accountDao.outMoney(from,money);
        int a = 2/0;
        accountDao.inMoney(to,money);
    }

    //如果这个方法不使用事物
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void trans2(String from, String to, double money) {
        accountDao.outMoney(from,money);
        int a = 2/0;
        accountDao.inMoney(to,money);
    }
}
发布了60 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44142032/article/details/92715268