27-SpringBoot——核心-声明式事务

SpringBoot——核心-声明式事务


【博文目录>>>】


【项目源码>>>】


【Spring 的事务机制】


而Spring 的事务机制是用统一的机制来处理不同数据访问技术的事务处理。Spring 的事务机制提供了一个PlatformTransactionManager 接口,不同的数据访问技术的事务使用不间的接口实现。

这里写图片描述

在程序中定义事务管理器的代码如下

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setDataSource(dataSource());

    return transactionManager;
}

【声明式事务】


Spring 支持声名式事务,即使用注解来选择需要使用事务的方法,它使用@Transactional注解在方法上表明该方法需要事务支持。这是一个基于AOP 的实现操作,被注解的方法在被调用时, Spring开启一个新的事务,当方法无异常运行结束后, Spring 会提交这个事务。

在此处需要特别注意的是,此@Transactional 注解来自org.springframework. transaction.annotation 包,而不是javax.transaction 。Spring 提供了一个@EnableTransactionManagement 注解在配置类上来开启声明式事务的支持。使用了@EnableTransactionManagement 后, Spring 容器会自动扫描注解@Transactional。

【注解事务行为】

@Transactional通过属性来定制事务行为,如下所示。

这里写图片描述
这里写图片描述

【类级到使用@Transactional】


@Transaction al 不仅可以注解在方法上,也可以注解在类上。注解在类上的时候意味着此类的所有public 方法都是开启事务的。如果类级别和方法级别同时使用了@Transactional 注解,则使用在类级别的注解会重载方法级别的注解。

【Spring Data JPA 的事务支持】


Spring Data JPA 对所有的默认方法都开启了事务支持,且查询类事务默认启用readOnly =true 属性。

【Spring Boot 的事务支持】


【自动配嚣的事务管理器】


在使用用JDBC 作为数据访问技术的时做, Spring Boot 为我们应义了PlatformTransactionManager 的实现DataSourceTransactionManager 的Bean; 配置见org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration 类中的定义

@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public DataSourceTransactionManager transactionManager(
      DataSourceProperties properties) {
   DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
         this.dataSource);
   if (this.transactionManagerCustomizers != null) {
      this.transactionManagerCustomizers.customize(transactionManager);
   }
   return transactionManager;
}

在使用JPA 作为数据访问技术的时候, Spring Boot 为我们了定义一个PlatformTransactionManager 的实现JpaTransaction Manager 的Bean :配置见org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration类中的定义:

@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager() {
   JpaTransactionManager transactionManager = new JpaTransactionManager();
   if (this.transactionManagerCustomizers != null) {
      this.transactionManagerCustomizers.customize(transactionManager);
   }
   return transactionManager;
}

【自动开启注解事务的支持】


Spring Boot 专门用于配置事务的类为: org.springframework.boot.autoconfigure. transaction.TransactionAutoConfiguration ,此配置类依赖于JpaBaseConfig和DataSourceTransactionManagerAutoConfiguration 。而在DataSourceTransactionManagerAutoConfiguration 配置里还开启了对声名式事务的支持。

@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
static class DataSourceTransactionManagerConfiguration {}

【代码实现】


application.properties

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc\:mysql\://localhost\:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456
#1
spring.jpa.hibernate.ddl-auto=update
#2
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true
package com.example.spring.boot.transaction.controller;

import com.example.spring.boot.transaction.domain.Person;
import com.example.spring.boot.transaction.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Author: 王俊超
 * Date: 2017-07-18 08:00
 * All Rights Reserved !!!
 */
@RestController
public class MyController {
    @Autowired
    DemoService demoService;

    @RequestMapping("/rollback")
    public Person rollback(Person person) { //1
        return demoService.savePersonWithRollBack(person);
    }

    @RequestMapping("/norollback")
    public Person noRollback(Person person) {//2
        return demoService.savePersonWithoutRollBack(person);
    }
}
package com.example.spring.boot.transaction.dao;

import com.example.spring.boot.transaction.domain.Person;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Author: 王俊超
 * Date: 2017-07-18 07:56
 * All Rights Reserved !!!
 */
public interface PersonRepository extends JpaRepository<Person, Long> {
}
package com.example.spring.boot.transaction.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * Author: 王俊超
 * Date: 2017-07-18 07:55
 * All Rights Reserved !!!
 */
@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private Integer age;

    private String address;


    public Person() {
        super();
    }

    public Person(Long id, String name, Integer age, String address) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

package com.example.spring.boot.transaction.service;

import com.example.spring.boot.transaction.domain.Person;

/**
 * Author: 王俊超
 * Date: 2017-07-18 07:57
 * All Rights Reserved !!!
 */
public interface DemoService {
    Person savePersonWithRollBack(Person person);
    Person savePersonWithoutRollBack(Person person);
}
package com.example.spring.boot.transaction.service.impl;

import com.example.spring.boot.transaction.dao.PersonRepository;
import com.example.spring.boot.transaction.domain.Person;
import com.example.spring.boot.transaction.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Author: 王俊超
 * Date: 2017-07-18 07:57
 * All Rights Reserved !!!
 */
@Service
public class DemoServiceImpl implements DemoService {

    @Autowired
    private PersonRepository personRepository;

    @Override
    @Transactional(rollbackFor = {IllegalArgumentException.class})
    public Person savePersonWithRollBack(Person person) {
        Person p = personRepository.save(person);

        if (person.getName().equals("王俊超")) {
            throw new IllegalArgumentException("王俊超已存在,数据将回滚"); //3
        }
        return p;
    }

    @Transactional(noRollbackFor = {IllegalArgumentException.class}) //4
    public Person savePersonWithoutRollBack(Person person) {
        Person p = personRepository.save(person);

        if (person.getName().equals("王俊超")) {
            throw new IllegalArgumentException("王俊超虽已存在,数据将不会回滚");
        }
        return p;
    }
}
package com.example.spring.boot.transaction;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Author: 王俊超
 * Date: 2017-07-18 07:43
 * All Rights Reserved !!!
 */
@SpringBootApplication
public class SampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值