Spring -事务操作

1、事务概念

a)事务是数据库操作的最基本单元,逻辑上一组操作,要么成功,如果有一个失败所有都失败。

2、事务特性(ACID)

a)原子性

b)一致性

c)隔离性

d)持久性

3、搭建事务操作环境

a)创建数据库表,添加记录

b)创建service,搭建dao,完成对象创建和注入

 (1)service注入dao,在dao中注入jdbcTemplate,jdbcTmplate中注入dateSource 

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    //转账
    public void accontMoney(){
        //多钱
        userDao.addMoney();
       //少钱
        userDao.raduceMoney();
    }
}

public interface UserDao {
    public void addMoney();

    public void raduceMoney();
}

@Repository
public class UserDaoImpl implements  UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    //多钱
    @Override
    public void addMoney() {
        String sql="update t_account set money=money+? where name=?";
        jdbcTemplate.update(sql,100,"jack");
    }
    //少钱
    @Override
    public void raduceMoney() {
        String sql="update t_account set money=money-? where name=?";
        jdbcTemplate.update(sql,100,"rose");
    }
} 

 (2)xml 配置

<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"
       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">

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///xz520?serverTimezone=UTC" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!--配置jdbcTmplate对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--注解驱动-->
    <context:component-scan base-package="com.spring"></context:component-scan>
</beans>

 (3)测试

public class SpringTest {
    @Test
    public void TestAdd(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
        UserService user=context.getBean("userService", UserService.class);
        user.accontMoney();
    }

}

 4、事务操作

a)事务添加到JavaEE三层的service层(业务逻辑层)

b)在Spring进行事务管理操作

(1)有两种方式:编程式事务管理和声明式事务管理(推荐使用)

c) 声明式事务管理

(1)基于注解方式(使用)

(2)基于xml配置文件方式

d) 在Spring进行声明式事务管理,底层使用AOP原理

e) Spring事务管理API

  (1) 提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

 

 注解声明事务管理

a) 在Spring配置文件配置事务管理器

<!--创建事务管理器-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

b)在Spring配置文件,开启事务注解

(1)在Spring配置文件中引入名称空间tx

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

(2)开始事务注解

 <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>

(3)在service类上添加注解(或者在service类的方法上添加注解)

    @Transactional ,这个注解可以加在类上,也可以加在方法上

  把注解加载类上,这个类里面的所有方法都添加了事务

 把注解加在方式上,只为这个方法添加了事务

@Service
@Transactional 
public class UserService {

    @Autowired
    private UserDao userDao;
    //转账
    public void accontMoney(){
        //多钱
        userDao.addMoney();

        //模拟异常
        int i=10/0;

       //少钱
        userDao.raduceMoney();
    }
}

在service类上添加注释@Transactionl,注解配置的事务相关参数

1、Propagation:事务传播行为 

多事务方法直接进行调用,在这个过程中事务是如何进行管理的

 

 

 

 Spring 框架事务传播行为有7种

REQUIRED:  如果add方法本身有事务,调用update方法之后,update使用当前的add方法的事务(默认)

              如果add方法本身没有事务,调用upadte方法之后,创建新的事务

REQUIRED_NEW: 使用add方法调用update方法,如果add无论是否有事务,都会创建新的事务,将已有的事务挂起

SUPPORTS: 如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中

NOT_SUPPORTE:  当前的方法不应该运行在事务中,如果有运行的事务,将它挂起

MANDATORY :当前的方法必须运行在事务内部,如果没有运行的事务,就抛出异常

NEVER: 当前的方法必须不应该运行在事务中,如果有运行的事务,就抛出异常

NESTED: 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行

2、isolation:事务隔离级别

(1)      事务有特性成为隔离性,多事务操作之间不会产生影响,不考虑隔离性产生很多问题

(2)      有三个读的问题:脏读、不可重复读、虚(幻)读

(3)      脏读:一个未提交事务被另一个未提交事务的数据

(4)      不可重复读:一个未提交事务读取到另一个已提交事务修改数据

(5)      虚读:一个未提交事务读取到另一个提交事务添加数据

  解决:通过设置事务隔离级别,解决读问题

 

3、timeout:超时时间:事务需要在一定的时间进行提交,以秒为单位 默认值为:-1

4、readOnly:是否只读:true 只可查询   false 可以查询也可以增删改

5、rollbackFor:回滚 :设置出现哪些异常进行回滚

6、noRollbackFor:不回滚:设置哪些异常不进行回滚

 XML声明式事务管理操作

1、在Spring配置文件中进行配置

a) 配置事务管理器

b) 配置通知

c) 配置切入点和切面

    <!--1、创建事务管理器--> 主要id中的名称固定为:transactionManager
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--2、配置通知-->
    <tx:advice id="tx">
        <!--配置事务参数-->
        <tx:attributes>
            <tx:method name="accontMoney" propagation="REQUIRED"/>
           <!-- <tx:method name="accont*" propagation="REQUIRED"/>-->
        </tx:attributes>
    </tx:advice>

    <!--3、配置切入点和切面-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="pt" expression="execution(* com.spring.service.UserService.*(..))"/>
        <!--配置切面-->
        <aop:advisor advice-ref="tx" pointcut-ref="pt"/>
    </aop:config>

 完全注解开发式事务管理操作

 1、创建一个配置类

@Configuration //配置类直接
@ComponentScan(basePackages = "com.spring") //注解扫描
@EnableTransactionManagement //事务注解
public class TxConfig {
    //配置数据库数据源
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource dataSource=new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///xz520?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
    //配置事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DruidDataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager=new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
    //配置JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DruidDataSource dataSource){
        JdbcTemplate jdbcTemplate=new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
}

测试类

 @Test
    public void TestAdd2(){
        ApplicationContext context=new AnnotationConfigApplicationContext(TxConfig.class);
        UserService user=context.getBean("userService", UserService.class);
        user.accontMoney();
    }
posted @ 2021-03-16 14:19  学习的过程就是成长  阅读(34)  评论(0)    收藏  举报