13 - Spring AOP介绍与使用4 - JdbcTemplate、声明式事务和传播特性、基于xml的事务配置

1、Spring JdbcTemplate

代码示例:

首先导入pom依赖:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zhoulz</groupId>
    <artifactId>spring_aop_tx</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--添加的maven依赖-->

        <!--添加的spring-context依赖-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <!--添加junit的依赖-->
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--添加的spring-aop依赖-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <!--cglib依赖-->
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

        <!--aspectj weaver依赖 —— 提供了一种功能更强的织入方式-->
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
            <!--<scope>runtime</scope>--> <!--这个一定要注释掉,不然@Aspect出不来-->
        </dependency>

        <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <!--除aop相关的一些依赖外,还要导入以下依赖:-->

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!--最后,因为和数据访问有关,还要导入JDBC、ORM、Transaction相关的依赖。这里已经自动导入了,因为依赖关系-->

    </dependencies>

</project>

然后,resources文件夹下,创建db.properties: (demo是对应的数据库)

jdbc.username=root
jdbc.password=123456
idbc.url=jdbc:mysql://localhost:3306/demo
jdbc.driverName=com.mysql.jdbc.Driver

然后,resources文件夹下,创建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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/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
       https://www.springframework.org/schema/aop/spring-aop.xsd
">
    <!--后加:-->
    <!--注解和配置文件是组合使用的:-->
    <!--如:这里EmpDao的注册用的即使注解,这里是扫描的操作,然后对应类及属性加上注解即可-->
    <context:component-scan base-package="com.zhoulz"></context:component-scan>



    <!--上面的context命名空间和下面这行代码导入进来后,下面输入时才有提示-->
    <context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true"></context:property-placeholder>
    <!--这里,需要在后面加上属性:ignore-unresolvable="true",不然test01()中连接不上数据库-->

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClassName" value="${jdbc.driverName}"></property>
        <property name="url" value="${jdbc.url}"></property>
    </bean>

    <!--spring 为我们提供了一个类:JdbcTemplate,它是属于包package org.springframework.jdbc.core;的,即属于spring里面的东西 -->
    <!--先把JdbcTemplate注册为Bean对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--下面的dataSource这个属性被要求有,必须定义-->
        <property name="dataSource" ref="dataSource"></property>
     </bean>

    <!--首先,要声明/添加 事务管理器--><!--即:配置事务管理器的bean对象-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--然后,接着还要导入tx的命名空间,见上面-->
    <!--再然后,就可以引入tx的一些注解了:--> <!--即:开启基于注解的事务管理器的配置-->
    <!--注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
    <!--以前的AOP是这样的,同样的操作-->
    <!--<aop:aspectj-autoproxy></aop:aspectj-autoproxy>-->
    <!--添加好事务管理器就可以引入相关的事务控制了,即:在BookService类的buyBook()方法上面添加上@Transactional注解即可-->

</beans>

接下来对数据库中的数据进行操作:增删改查

Dao 接口:

package com.zhoulz.dao;

import com.zhoulz.entity.Emp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public interface Dao {

    @Autowired
    public void save(Emp emp);
}

接口对应的实现类:EmpDao

package com.zhoulz.dao;

import com.zhoulz.entity.Emp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class EmpDao implements Dao{
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void save(Emp emp){  //测试见test08()
        String sql = "insert into emp(empno,ename) value(?,?)";
        int update = jdbcTemplate.update(sql, emp.getEmpno(), emp.getEname());
        System.out.println(update);
    }
}

entity文件夹下的 Emp 类 (常规代码)—— 对应数据库?

package com.zhoulz.entity;

import java.util.Date;

public class Emp {
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;

    public Emp() {
    }

    public Emp(Integer empno, String ename) {
        this.empno = empno;
        this.ename = ename;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getComm() {
        return comm;
    }

    public void setComm(Double comm) {
        this.comm = comm;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", comm=" + comm +
                ", deptno=" + deptno +
                '}';
    }
}

测试类:MyTest

import com.alibaba.druid.pool.DruidDataSource;
import com.zhoulz.dao.EmpDao;
import com.zhoulz.entity.Emp;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class MyTest {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    @Test
    public void test01() throws SQLException {
        DruidDataSource dataSource = context.getBean("dataSource", DruidDataSource.class);
        System.out.println(dataSource.getConnection()); //测试没成功
        //System.out.println(dataSource.getClass());
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        System.out.println(jdbcTemplate);
    }

    //测试对数据的增删改查  —— 加入单条数据
    @Test
    public void test02(){
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        //不能直接jdbcTemplate.insert,也没有提示有insert这个方法
        //应该先写sql语句
        String sql = "insert into emp(empno,ename) value(?,?)";
        int zhangsan = jdbcTemplate.update(sql, 1111, "zhangsan");
        System.out.println(zhangsan);
    }

    //批量加入数据
    @Test
    public void test03(){
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "insert into emp(empno,ename) value(?,?)";
        List<Object[]> list = new ArrayList<Object[]>();
        list.add(new Object[]{2222,"lisi"});
        list.add(new Object[]{3333,"wangwu"});
        list.add(new Object[]{4444,"maliu"});
        //int zhangsan = jdbcTemplate.update(sql, 1111, "zhangsan");
        int[] result = jdbcTemplate.batchUpdate(sql, list);
        for (int i : result) {
            System.out.println(i);
        }
    }

    //删除数据
    @Test
    public void test04(){
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        //String sql = "insert into emp(empno,ename) value(?,?)";
        String sql = "delete from emp where empno = ?";
        int zhangsan = jdbcTemplate.update(sql, 1111);
        System.out.println(zhangsan);
    }

    //修改数据
    @Test
    public void test05(){
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        //String sql = "insert into emp(empno,ename) value(?,?)";
        String sql = "update emp set ename = ? where empno = ?";
        int zhangsan = jdbcTemplate.update(sql,"zhouzhou",2222);
        System.out.println(zhangsan);
    }

    //查询数据 (稍微复杂点)—— 用的是query()
    //查询一条数据
    @Test
    public void test06(){
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "select * from emp where empno = ?";
        Emp result = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Emp.class),7902);
        System.out.println(result);
    }

    //查询多条数据(集合)
    @Test
    public void test07(){
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "select * from emp where sal > ?";
        List<Emp> result = jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Emp.class),1500);
        //System.out.println(result);
        for (Emp emp : result) {
            System.out.println(emp);
        }
    }

    @Test
    public void test08(){
        EmpDao empDao = context.getBean("empDao", EmpDao.class);
        empDao.save(new Emp(1111,"zhangsan2"));
    }
}

2、声明式事务

参考:0 - Spring —— 相关_哆啦A梦的_梦的博客-CSDN博客

(四、java要知道 ——> 1、声明式事务)daimashili 

(1)— (8)声明式事务 设置、属性等

代码示例:

首先,resources层下applicationContext.xml的配置见上。

dao层下的 BookDao类:

package com.zhoulz.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class BookDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //方法
    //1、减去某个用户的余额
    public void updateBalance(String userName,int price){
        String sql = "update account set balance=balance-? where userName=?";
        jdbcTemplate.update(sql,price,userName);
    }
    //2、按照图书的id来获取图书的价格
    public int getPrice(int id){
        String sql = "select price from book where id = ?";
        return jdbcTemplate.queryForObject(sql,Integer.class,id); //Integer.class ???
    }
    //3、减库存,减去某本书的库存
    public void updateStock(int id){
        String sql = "update book_stock set stock=stock-1 where id=?";
        jdbcTemplate.update(sql,id);
    }
}

service层下的 BookService 类:

package com.zhoulz.service;

import com.zhoulz.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.awt.print.Book;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    /**声明式事务的相关参数:
     *
     * 1、propagation:传播特性:表示不同的事务之间执行的关系
     * 2、ioslation:隔离级别:4种隔离级别,会引发不同的数据错乱问题
     * (上面的1/2较为复杂)
     *
     * 3、timeout:超时时间(s):如果事务超过所设置的超时时间的话,则事务会进行正常的回滚。
     *     即:超过所设置的超时时间时(说明没执行完),事务会正常回滚(即,操作都不执行);
     *         而在所设置的超时时间内时,操作都会成功执行。
     * 4、readonly:只读事务(默认值false)
     *     即:如果配置了只读事务,那么在事务运行期间,不允许对数据进行修改,否则抛出异常。
     * 5、noRollBackerfor(设置哪些异常不回滚,即:即使出现异常了,也让它继续执行):
     * 6、noRollbackerForClassName:
     * (上面两个意思是一样的,只不过传的对象不一样,noRollBackerfor传的是class,noRollbackerForClassName传的是String)
     *
     * 7、rollBackfor:(设置哪些异常回滚,即操作都不执行)
     * 8、rollbackForClassName:
     * */

    //声明事务: 引入事务控制。然后就可以进行事务回滚等操作
    //@Transactional(timeout = 4)

    //@Transactional(noRollbackFor = {ArithmeticException.class})
    //换个写法:
    //@Transactional(noRollbackForClassName = {"java.lang.ArithmeticException"})

   //@Transactional(rollbackFor = {FileNotFoundException.class})
    //换个写法
    //@Transactional(rollbackForClassName = {"java.io.FileNotFoundException"})

    //隔离级别 ioslation:
    //@Transactional(isolation = Isolation.DEFAULT) ——匹配对应的数据库
    //@Transactional(isolation = Isolation.READ_COMMITTED) //读与提交
    //@Transactional(isolation = Isolation.READ_UNCOMMITTED)
    //@Transactional(isolation = Isolation.REPEATABLE_READ) //可重复读
    //@Transactional(isolation = Isolation.SERIALIZABLE) //序列化
    @Transactional
    public void buyBook() throws FileNotFoundException {
        bookDao.getPrice(1);
        bookDao.updateBalance("zhangsan",100);
        //int i = 1/0; //会导致事务的中断,用来测试
        //Thread.sleep(3000);
        bookDao.updateStock(1);
        new FileInputStream("aaa.txt");
    }
}

测试类:MyTest2

import com.zhoulz.service.BookService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.FileNotFoundException;

public class MyTest2 {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    @Test
    public void test01() throws FileNotFoundException {
        BookService bean = context.getBean(/*"bookService",*/BookService.class);
        JdbcTemplate jdbcTemplate = context.getBean("jdbcTemplate", JdbcTemplate.class);
        System.out.println(jdbcTemplate);
        bean.buyBook();
    }
}

(9) 事务的传播特性

(10)测试事务的传播特性

用的比较多的是 :REQUIRED 和 REQUIRES_NEW。

REQUIRED

如果事务里面包括一些子事务,则最终的操作都是由外部的事务来整体控制(即,如果一个子事务出错了,那么都进行回滚,都没有修改)。这里,外部是指 MultService类下mutl() 方法。如果把外部mutl() 方法的事务去掉(注释掉@Transactional),则实现不了整体控制(里面的子事务互不影响,报错的就回滚,没报错的就正常执行)。

REQUIRES_NEW

子事务之间,如果声明为REQUIRES_NEW 的话,则互为独立(独立是指先挂起,等其他的执行完了再执行)的。即:异常了就回滚,没异常则正常执行,不受其他子事务异常的影响。

其他的传播特性  —— 待看。

NESTED:—— 常与 REQUIRED 作比较        “嵌套”

 代码示例:

dao层下的BookDao类:

package com.zhoulz.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class BookDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //方法
    //1、减去某个用户的余额
    public void updateBalance(String userName,int price){
        String sql = "update account set balance=balance-? where userName=?";
        jdbcTemplate.update(sql,price,userName);
    }
    //2、按照图书的id来获取图书的价格
    public int getPrice(int id){
        String sql = "select price from book where id = ?";
        return jdbcTemplate.queryForObject(sql,Integer.class,id); //Integer.class ???
    }
    //3、减库存,减去某本书的库存
    public void updateStock(int id){
        String sql = "update book_stock set stock=stock-1 where id=?";
        jdbcTemplate.update(sql,id);
    }

    //再加一个方法
    //4、更新价格
    public void updatePrice(int id){
        String sql = "update book set price=price-1 where id=?";
        jdbcTemplate.update(sql,id);
    }
}

service层下的 BookService 类:

package com.zhoulz.service;

import com.zhoulz.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.awt.print.Book;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    //@Transactional(propagation = Propagation.REQUIRED)
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void buyBook() {
        bookDao.getPrice(1);
        bookDao.updateBalance("zhangsan",100);
        //int i = 1/0; //会导致事务的中断,用来测试
        //Thread.sleep(3000);
        bookDao.updateStock(1);
        //new FileInputStream("aaa.txt");
    }

    //也写一个updatePrice()方法,调用BookDao中的updatePrice()方法
    @Transactional(propagation = Propagation.REQUIRED)
    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updatePrice(){
        bookDao.updatePrice(1);
        int i = 1/0;
    }
}

service层下的 MultService 类:

package com.zhoulz.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MultService {
    @Autowired
    private BookService bookService;

    @Transactional
    public void mult(){
        //bookService.updatePrice();
        bookService.buyBook();
        bookService.updatePrice();
    }
}

测试类:MyTest3

import com.zhoulz.service.MultService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest3 {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    @Test
    public void test01(){
        MultService bean = context.getBean(MultService.class);
        bean.mult();
    }
}

3、基于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: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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       https://www.springframework.org/schema/tx/spring-tx.xsd
">
    <!--分为bean对象的配置和事务的配置-->
    
    <!-- 一、bean对象的配置-->

    <!--1、定义扫描包 — 扫描一些基本的包。 这样不用每个bean都单独写-->
    <context:component-scan base-package="com.zhoulz"></context:component-scan>

    <!--2、进行事务操作的话,必然要连接数据库,所以要把外部数据属性的配置文件加入进来,比如db.properties-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--3、还用到了一个druid(德鲁伊)的数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!--然后写上一些对应的属性:-->
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driverNamee}"></property>
    </bean>

    <!--4、还有JdbcTemplate对应的配置:-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 二、事务的配置:-->
    <!--1、首先,声明一个事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--声明式事务是依托于AOP的,所以AOP的配置必须要有-->
    <!--2、AOP配置-->
    <aop:config>
        <!--然后是aop中切面之类的-->
        <aop:pointcut id="txPointcut" expression="execution(* com.zhoulz.service.*.*(..))"/>
        <!--事务建议(这里事务还没配)-->
        <aop:advisor advice-ref="myAdvice" pointcut-ref="txPointcut"></aop:advisor>
    </aop:config>

    <!--事务的话,有专门的事务标签 (对应上面的事务建议)-->
    <!--3、事务标签(然后把下面的myAdvice拿上去)-->
    <tx:advice id="myAdvice" transaction-manager="transactionManager">
        <!--配置事务的属性-->
        <tx:attributes>
            <!--配置咋哪些方法上添加事务-->
            <tx:method name="addBook" propagation="REQUIRED" read-only="true" isolation="DEFAULT"/>
            <tx:method name="updatePrice" propagation="REQUIRED"></tx:method>
            <!--有通配符的写法:-->
            <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="update*" propagation="REQUIRES_NEW"></tx:method>
        </tx:attributes>
    </tx:advice>
</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值