Spring事务管理-注解方式实现+XML方式实现

 

目录

1、事务概念与事务的四个特性ACID

2、事务操作(搭建事务操作环境)

3、事务操作(Spring事务管理介绍)

4、事务操作(注解实现-声名式事务)

4.1 事务操作(声名式事务的参数设置)

5、事务操作(XML配置文件实现-声名式事务)

6、事务操作(完全注解式实现-声名式事务)

6.1 使用完全注解方式实现事务管理的代码如下:

附录0:Spring事务测试的项目结构

附录1:注解方式实现声名式事务代码

附录1-1:UserDao接口

附录1-2:UserDao接口的实现

附录1-3:事务类:UserServiceTx

附录1-4:Spring配置文件:bean1.xml

附录1-5:声名式事务测试类

附录2:XML方式实现声名式事务代码

附录2-1:UserDao接口

附录2-2:UserDao接口的实现

附录2-3:事务类:UserServiceTx

附录2-4:Spring配置文件:bean2.xml

附录2-5:声名式事务测试类


1、事务概念与事务的四个特性ACID

2、事务操作(搭建事务操作环境)

CREATE TABLE `RUN_Account` (
  `Id` int(20) NOT NULL AUTO_INCREMENT COMMENT '用户Id',
  `Name` varchar(32) NOT NULL DEFAULT '' COMMENT '姓名',
  `Money` int(20) NOT NULL DEFAULT 0 COMMENT '账户余额',
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='账户表';

insert into RUN_Account(name,money) values ("lucy",1000);
insert into RUN_Account(name,money) values ("marry",1000);
select * from RUN_Account;

3、事务操作(Spring事务管理介绍)

4、事务操作(注解实现-声名式事务)

4.1 事务操作(声名式事务的参数设置)

5、事务操作(XML配置文件实现-声名式事务)

6、事务操作(完全注解式实现-声名式事务)

6.1 使用完全注解方式实现事务管理的代码如下:

package com.wind.spring5.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @Description: 完全注解实现声名式事务
 */
@Configuration //声名这是一个配置类
@ComponentScan(basePackages = "com.wind.*") //开启组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {

    //1.创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/RUNOOB?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("root");
        return druidDataSource;
    }

    //2.创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DruidDataSource druidDataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //到IOC容器中根据类型找到druidDataSource,然后注入到JDBC对象中
        jdbcTemplate.setDataSource(druidDataSource);
        return jdbcTemplate;
    }

    //3.创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DruidDataSource druidDataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(druidDataSource);
        return dataSourceTransactionManager;
    }
}
package com.wind.spring5.test;

import com.wind.spring5.config.TxConfig;
import com.wind.spring5.service.UserServiceTx;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

/**
 * @Description: 完全注解方式实现事务时,需要的文件详见:
 * 1.被增强的类:UserServiceTx
 * 2.完全注解类:TxConfig.class
 * 3.测试类:UserServiceTxConfigTest
 */
@Component
public class UserServiceTxConfigTest {

    @Test
    public void userServiceTest() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TxConfig.class);
        /**
         * 使用完全注解形式实现的声名式事务演示
         */
        UserServiceTx userServiceTx = applicationContext.getBean("userServiceTx", UserServiceTx.class);
        userServiceTx.accountMoney();
        System.out.println(1);
    }
}

附录0:Spring事务测试的项目结构

##数据库驱动
jdbc.driverClassName=com.mysql.jdbc.Driver
##MySQL连接信息
jdbc.url=jdbc:mysql://127.0.0.1:3306/RUNOOB?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT
##用户名
jdbc.username=root
##密码
jdbc.password=root

附录1:注解方式实现声名式事务代码

附录1-1:UserDao接口

@Repository
public interface UserDao {
    void reduceMoney();
    void addMoney();
}

附录1-2:UserDao接口的实现

@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void reduceMoney() {
        String sql = "update RUN_Account set money = money - ? where name = ?";
        Object[] args = {100, "lucy"};
        jdbcTemplate.update(sql, args);
    }

    @Override
    public void addMoney() {
        String sql = "update RUN_Account set money = money + ? where name = ?";
        Object[] args = {100, "marry"};
        jdbcTemplate.update(sql, args);
    }
}

附录1-3:事务类:UserServiceTx

/**
 * @Description: 推荐使用的是声名式事务:这是注解的方式实现的,详见Spring配置文件:bean1.xml
 * 事务管理的参数:
 * 1.propagation:事务传播行为
 * 2.isolation:事务隔离级别
 * 3.timeout:事务超时时间
 * 4.readonly:事务是否只能做读操作而不能做非读操作
 * 5.rollbackFor:遇到了哪些异常,进行事务回滚
 * 6.noRollbackFor:遇到了哪些异常,不进行事务回滚
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, timeout = -1, readOnly = false)
public class UserServiceTx {
    @Autowired
    private UserDao userDao;

    public void accountMoney() {
        //lucy少钱
        userDao.reduceMoney();
        //模拟程序异常
        double i = 10 / 0;
        //marry多钱
        userDao.addMoney();
    }
}

附录1-4:Spring配置文件:bean1.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 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">

    <!--开启SpringBean的组件扫描-->
    <context:component-scan base-package="com.wind.spring5"/>

    <!--在Spring配置文件开启自动生成代理对象-->
    <aop:aspectj-autoproxy/>

    <!--获取Spring需要读取的数据库配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据源:使用德鲁伊数据库连接池这个工具配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--创建JdbcTemplate对象,同时使用set方法注入dataSource属性-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--1.在Spring配置文件中,使用声名式事务时需要创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--2.在Spring配置文件中,开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

附录1-5:声名式事务测试类

/**
 * @Description: 注解方式实现事务时,需要的文件详见:
 * 1.被增强的类:UserServiceTx
 * 2.注解形式配置的Spring配置文件:bean1.xml
 * 3.测试类:UserServiceTxTest
 */
@Component
public class UserServiceTxTest {
    @Test
    public void userServiceTest() {
        String spring = "bean1.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(spring);
        /**
         * 未使用事务时的演示
         */
        //UserServiceNoTx userServiceNoTx = applicationContext.getBean("userService", UserServiceNoTx.class);
        //userServiceNoTx.accountMoney();
        //System.out.println(1);
        /**
         * 使用声名式事务时的演示
         */
        UserServiceTx userServiceTx = applicationContext.getBean("userServiceTx", UserServiceTx.class);
        userServiceTx.accountMoney();
        System.out.println(1);
    }
}

附录2:XML方式实现声名式事务代码

附录2-1:UserDao接口

@Repository
public interface UserDao {
    void reduceMoney();
    void addMoney();
}

附录2-2:UserDao接口的实现

@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void reduceMoney() {
        String sql = "update RUN_Account set money = money - ? where name = ?";
        Object[] args = {100, "lucy"};
        jdbcTemplate.update(sql, args);
    }

    @Override
    public void addMoney() {
        String sql = "update RUN_Account set money = money + ? where name = ?";
        Object[] args = {100, "marry"};
        jdbcTemplate.update(sql, args);
    }
}

附录2-3:事务类:UserServiceTx

/**
 * @Description: 推荐使用的是声名式事务:这是XML的方式实现的,详见Spring配置文件:bean2.xml
 * 事务管理的参数:
 * 1.propagation:事务传播行为
 * 2.isolation:事务隔离级别
 * 3.timeout:事务超时时间
 * 4.readonly:事务是否只能做读操作而不能做非读操作
 * 5.rollbackFor:遇到了哪些异常,进行事务回滚
 * 6.noRollbackFor:遇到了哪些异常,不进行事务回滚
 */
@Service
public class UserServiceTxXML {
    @Autowired
    private UserDao userDao;

    public void accountMoney() {
        //lucy少钱
        userDao.reduceMoney();
        //模拟程序异常
        double i = 10 / 0;
        //marry多钱
        userDao.addMoney();
    }
}

附录2-4:Spring配置文件:bean2.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 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">

    <!--开启SpringBean的组件扫描-->
    <context:component-scan base-package="com.wind.spring5"/>

    <!--在Spring配置文件开启自动生成代理对象-->
    <aop:aspectj-autoproxy/>

    <!--获取Spring需要读取的数据库配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据源:使用德鲁伊数据库连接池这个工具配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--创建JdbcTemplate对象,同时使用set方法注入dataSource属性-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--1.配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--配置事务的数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--2.配置通知:增强的逻辑-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="accountMoney" propagation="REQUIRED"/>
            <!--account开头的方法都会被增强-->
            <!--<tx:method name="account*" propagation="REQUIRED"/>-->
        </tx:attributes>
    </tx:advice>

    <!--3.配置切入点和切面-->
    <aop:config>
        <!--配置切入点:被增强的方法-->
        <aop:pointcut id="pc" expression="execution(* com.wind.spring5.service.UserServiceTxXML.*(..))"/>
        <!--配置切面:把通知织入到切入点的过程-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    </aop:config>

</beans>

附录2-5:声名式事务测试类

/**
 * @Description: XML方式实现事务时,需要的文件详见:
 * 1.被增强的类:UserServiceTxXML
 * 2.XML形式配置的Spring配置文件:bean2.xml
 * 3.测试类:UserServiceTxXMLTest
 */
@Component
public class UserServiceTxXMLTest {

    @Test
    public void userServiceTest() {
        String spring = "bean2.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(spring);
        /**
         * 使用声名式事务时的演示
         */
        UserServiceTxXML userServiceTxXML = applicationContext.getBean("userServiceTxXML", UserServiceTxXML.class);
        userServiceTxXML.accountMoney();
        System.out.println(1);
    }

}

猜你喜欢

转载自blog.csdn.net/cmm0401/article/details/111397844