事务管理配置

事务管理配置

使用Spring提供的事务管理切面类 完成DAO中增删改操作的事务管理

1.1 事务的隔离级别

isolation 设置事务隔离级别: READ_UNCOMMITTED ,READ_COMMITTED , REPEATABLE_READ
, SERIALIZABLE

串行化:T1在执行的过程中,T2既不能读也不能写
可重复读:T1在执行的过程中,T2只能能读但不能改,T2可以添加数据(幻读)
读已提交:T1在执行的过程中,T2可以读也可以写,但是T1只能读取到T2提交后的数据(不可重复读)(幻读)
读未提交:T1在执行的过程中,T2可以读也可以写,T1可以读取到T2未提交的数据(脏读)(不可重复读)(幻读)

1.2 事务的传播机制

propagation 设置事务的传播机制

名称说明
PROPAGATION_REQUIRED默认的 ,如果当前没有事务,就新建一个事务;如果当前已经存在一个事务,就加入
PROPAGATION_SUPPORTS如果当前有事务,则使用当前事务;如果当前没有事务,就以非事务方法执行
PROPAGATION_MANDATORY如果当前有事务,则使用当前事务;如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW无论当前有没有事务,就要创建一个新的事务;如果当前存在事务,就把当前的事务挂起(暂停)
PROPAGATION_NOT_SUPPORTED无论当前有没有事务,都以非事务的方式执行;如果当前存在事务,就把当前的事务挂起(暂停)
PROPAGATION_NEVER以非事务方式执行操作,如果存在事务,抛出异常
PROPAGATION_NESTED如果当前存在事务,则以子事务在嵌套事务内部执行;如果没有,就类似于 PROPAGATION_REQUIRED ,新建一个事务
@Service
public class StudentServiceTest {
    @Autowired
    private StudentService1 studentService1;
    @Autowired
    private StudentService2 studentService2;
    
 @Transactional(propagation = Propagation.REQUIRED)
    public void test(){
/**
 * 1.验证手机号,作为用户名,拿到用户的密码 ==> 用户表 1
 * 2.权限 跟插入用户表的操作返回的用户id
 * 做一些权限列表的绑定 ==>插入到中间表(对用id==某一个权限)
 * id userid permissionid
 * 1 1 1
 * 2 1 2
 * 3 1 3
 */
        studentService1.batchInsertCY();
         throw new RuntimeException("无中生有的异常");
    }
}
/**
 * @author muzi@softeem.com
 * @description @Transactional放在类上面,表示声明式事务的作用范围是该类中的
 * 所有方法,默认使用REQUIRED传播行为
 * @since 2021/4/13 20:28
 */
@Service
public class StudentService1 {
    @Autowired
    private StudentDao studentDao;
    @Transactional(propagation = Propagation.REQUIRED)
    public void batchInsertCY() {
        try {
            for (int i = 0; i < 10; i++) {
                 if (i == 5) {
                     throw new RuntimeException("无中生有的异常");
                     }
                Student student = new Student();
                student.setId(200 + i);
                student.setName("陈禹" + i);
                student.setAddress("东北三省" + i);
                studentDao.insert(student);
            }
        } catch (Exception e) {
//捕捉异常,但是不再抛出,相当于内部消化了该异常
            e.printStackTrace();
            throw e;
        }
    }
}

1.3 编程式事务

<!-- Spring事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
@Repository
public class StudentDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private DataSourceTransactionManager transactionManager;
    public void selectById(Integer id) {
        String sql = "SELECT id,name FROM student WHERE id=?";
        Student student = jdbcTemplate.queryForObject(sql, new Object[]{id}, new
                BeanPropertyRowMapper<>(Student.class));
        System.out.println(student);
    }
    public void batchInsert(List<Student> students){
        String sql = "INSERT INTO student(id,name) VALUES(?,?)";
         //创建事务
        DefaultTransactionDefinition defaultTransactionDefinition = new
                DefaultTransactionDefinition();
         //开启事务
        TransactionStatus status =
                transactionManager.getTransaction(defaultTransactionDefinition);
        try {
            for (int i = 0; i < students.size(); i++) {
                if (i == 4) {
                    throw new RuntimeException("无中生有的异常");
                }
                jdbcTemplate.update(sql, students.get(i).getId(),
                        students.get(i).getName());
            }
            //提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            System.err.println("发生异常");
             //回滚
            transactionManager.rollback(status);
        }
    }
}

1.4 声明式事务

由于声明式事务是SpringAOP的典型实现,SpringAOP又依赖于AspectJ,所以一定要加入这个依赖

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>

1.4.1 Spring AOP事务管理配置—XML配置

<!--1.将Spring提供的事务管理配置配置给Spring容器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="druidDataSource"/>
</bean>

<!--2.通过Spring jdbc提供的 tx标签,声明事务管理策略-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="insert*" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
    <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
    <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
    <tx:method name="query*" isolation="REPEATABLE_READ" propagation="SUPPORTS"/>
  </tx:attributes>
</tx:advice>

<!--3.将事务管理策略以AOP(切面切入点)配置 应用于DAO操作方法-->
<aop:config>
  <aop:pointcut id="crud" expression="execution(* com.cg.service.*.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="crud"/>
</aop:config>

1.4.2 Spring AOP事务管理配置—注解配置

  • 在applicationContext.xml中配置事务管理,声明使用注解方式进行事务配置

    <!--使用注解进行事务管理前提是 IoC需要进行注解配置-->
    <context:annotation-config/>
    <context:component-scan base-package="com.cg"/>
    
    <!--1.将Spring提供的事务管理配置配置给Spring容器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="druidDataSource"/>
    </bean>
    
    <!--2.声明使用注解完成事务配置-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
  • 在需要Spring进行事务管理的方法上添加 @Transactional 注解

    @Transactional(isolation = Isolation.REPEATABLE_READ ,propagation =  Propagation.SUPPORTS )
    public List<User> listUsers() {
    return userDAO.queryUsers();
    }
    

    @Transactional 可以用在 方法 上,代表给某个方法加上声明式事务,可以指定一些元配置信息,比如Propagation , isolation , timeout 和 readOnly ,建议加上 rollbackFor 属性,阿里规范
    @Transactional也可以用在 类 上,达标给该类下所有的方法加入声明式事务
    如果方法和类都有该注解,而且元配置信息不一致的情况下,遵循 就近原则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值