0
点赞
收藏
分享

微信扫一扫

Spring(三)事务

Separes 2022-03-23 阅读 39
springjava

事务的四大特性:ACID

  • 原子性:要么都成功,要么都失败
  • 一致性:事务前后的数据完整性要保证一致
  • 隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启事务。不能被其他的操作数据所干扰,多个并发事务之间要相互隔离
  • 持久性:事务一旦提交,就不可逆转,被持久化到数据库中.
    在这里插入图片描述
    模拟银行转账实例:
@Repository
public class UserDaoImpl implements UserDao{

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void addMoney() {
        String sql = "update acount set money = money+? where name = ?";
        jdbcTemplate.update(sql,100,"小李");

    }

    @Override
    public void reduceMoney() {
        String sql = "update acount set money = money-? where name = ?";
        jdbcTemplate.update(sql,100,"小王");
    }
}

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public void acountMoney(){
        userDao.reduceMoney();
        int i = 10/0;
        userDao.addMoney();
    }
}

在这里插入图片描述
我们是故意加了一个异常,在遇到异常的时候,这个情况就出现了大问题,小李钱增多了,小王钱却没变,所以要引入事务的操作,接下来看。

spring中的事务分两种:.编程式事务和声明式事务,
声明式事务分两种:1.基于xml方式 2.基于注解的方式
编程式事务就是在代码层面添加事务,用代码的方式。
spring在进行声明式事务时,底层使用的就是aop原理。
spring对事务管理提供了api,在我们使用不同的框架时也会有不同的实现。

在这里插入图片描述
现在做基于注解实现的事务:
1.需要先创建一个事务管理器,在里面开启我们用到的数据源

    <!--开启事务管理器,注入数据源-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

2.我们在service层加事务注解开启事务,因为service层时处理业务逻辑的,它也得调用dao层,所以我们在这层加事务最合适不过了。
事务@Transtional注解,在类上加代表这个类开启了事务,这类里面的方法要么都是成功要么同时失败,失败了,不会像之前一样,一个人变了,另一个人没变,失败就会开启一个回滚的操作,这样就会恢复原样。

@Trantstional里面的参数解析:
1.propagation:事务的传播行为
事务的传播行为分7种:
(1):REQUIRED:如果当前有事务在运行,就用当前的事务,如果当前没有事务在运行,就会开启一个新的事务,在这个新的事务种运行;
在这里插入图片描述
(2):REQUIRED_NEW:不管有没有事务,都会开启一个新的事务,在新的事务种运行,如果本身自己有事务,这个自己的事务直接挂起,还是用新的事务运行。
那几种不常用,暂且先记住这俩。
2.ioslation:事务的隔离级别
先说一下事务的隔离级别可能导致的问题,脏读,幻读,不可重复读
脏读:一个事务读取到了别的事务尚未提交的数据
不可重复度:一个事务读取到了别的事务提交前后的数据,(表示一个事务读取表中的一行数据,多次读取结果不一致的问题。
幻读:一个事务读取到了别的事务提交后的数据,导致前后读取结果不一致的问题。
3.timeout:超时时间:指一个事务在设置的时间内,如果未提交,就会执行回滚的操作。默认值是-1,意思就是不超时,以秒为单位,
4.readonly:是否只读,读:查询操作 写:修改的操作,readonly默认值是false,为false的话可以进行查询和修改操作,如果为true,只能进行查询操作。
5.rollbackfor:回滚:设置出现了哪些异常就进行回滚操作
6.norollbackfor:不回滚 :设置出现了哪些异常不进行回滚操作。

spring完全采用注解开发的事务:
1.要想取代xml,首先我们需要整一个配置类,在这里面做xml的一些事情。

package com.zhang.txConfig;

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;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.zhang")
public class TxConfigBean {

    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource source = new DruidDataSource();
        source.setUrl("jdbc:mysql://localhost:3306/mybatis?useSSL=false");
        source.setDriverClassName("com.mysql.jdbc.Driver");
        source.setUsername("root");
        source.setPassword("123456");
        return source;
    }

    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource);
        return manager;
    }
}

ok

举报

相关推荐

0 条评论