mybatis事务的初级使用

系列文章目录

1.mybatis的初级使用
2.mybatis关于association的使用



前言

记录学习mybatis关于事务方面的内容。


一、事务是什么?

事务是一个操作序列,它具有ACID四大特性。

  • 原子性:整个操作过程要么全做,要么全不做。
  • 一致性:事务按照预期生效,不管操作是成功,还是失败,数据的状态是人可以预期到的(数据库操作后的结果应该和人为推演一遍的结果一致)。
  • 隔离性:不同的事务之间互不干扰。
  • 持久性:一旦进行了操作,那操作的结果对数据库的改变是永久的。

二、mybatis事务的传播属性

当多个事务存在时,spring会采取的各种处理方式。

  • Propagation.REQUIRED(required):如果当前有事务, 那么加入事务, 如果当前没有事务,则新建一个(Spring默认的选择)
  • Propagation.NOT_SUPPORTED(not_supported) :如果当前存在事务就把当前事务挂起,执行完后恢复事务(忽略当前事务);
  • Propagation.SUPPORTS (supports) :如果当前有事务则加入,没有则不用事务。
  • Propagation.MANDATORY (mandatory) :如果当前没有事务,则抛出异常。(当前必须有事务)
  • PROPAGATION_NEVER (never) :以非事务方式执行,如果当前存在事务,则抛出异常。(当前必须不能有事务)
    Propagation.REQUIRES_NEW (requires_new) :如果当前有事务,则挂起当前事务,然后新创建一个事务。如果当前没有事务,则自己创建一个事务。

三、spring boot中使用事务

1.前提

想要在springboot中使用事务,有两大前提:

  • 数据库的引擎需要支持事务。比如MySQL中InnoDB支持事务,而MyISAM是不支持的。
  • 确保调用事务的方法是spring的代理对象,而不是真实的对象。直接用真实对象调用是不会触发事务的。(这种状况常发生在非事务方法的内部直接调用同一个类中的事务方法)

2.mybatis配置

pom.xml:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
    </dependencies>

application.properties(喜欢用yml的,自己改成yml风格就行):

// 设置服务器端口,随便改
server.port=8081
// 配置jdbc(我用的是MySQL,其他数据库自己改一下)
spring.datasource.url = jdbc:mysql://localhost:3306/你的数据库名?setUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.data-username= 你的用户名
spring.datasource.data-password= 你的密码
// 配置mybatis的mapper.xml文件位置
mybatis.mapper-locations= org/example/mapper/*.xml
// 给实体类取别名,说白了就是以后在mapper.xml中声明实体类时不用指明路径了
mybatis.type-aliases-package= org.example.domain

3.写案例

这里简单模拟了一下新增订单案例。

1. 实体类

public class Order {
    private Integer id;
    private String status;
    private String message;
}

2. mapper类

@Mapper
public interface OrderMapper {
    List<Order> getAllInfo();
	// 新增订单
    void insertOne(Order order);
}

对应的xml文件:

    <insert id="insertOne" parameterType="Order" useGeneratedKeys="true" keyProperty="id">
        insert into order_tbl(status, message) values (#{status}, #{message})
    </insert>

3. service实现类

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;

    //插入一条订单,返回主键
    private String addOrder(Order order) {
        orderMapper.insertOne(order);
        return order.getId().toString();
    }
    // 事务方法调用非事务方法时,非事务方法同样被加入事务中
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String create() {
        Order order = new Order();
        order.setMessage("无");
        order.setStatus("未支付");
        String orderId = addOrder(order);
		// 主动设置的报错,事务只有在报错后才会回滚
        int a = 1/0;
        return "下单成功" + "主键为:" + orderId;
    }
}

4. controller类

@RequestMapping("/order")
public class OrderController {
    @Autowired
    OrderService orderService;

    @GetMapping("/add")
    public String add() {
        return orderService.create();
    }
}

结果:在浏览器端访问后,会报分母为0的错,而数据库端是不会有新增数据的。但当去掉故意报错的那条语句后,数据库端会新增一条语句。


总结

记录单个事务回滚的使用过程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值