springboot mysql死锁_Spring Boot 整合 MyBatis 实现乐观锁和悲观锁

本文通过转账操作示例,详细讲解了Spring Boot与MyBatis如何实现乐观锁和悲观锁,以解决死锁问题。介绍了悲观锁的`select ... for update`用法和乐观锁的`version`字段更新策略,并通过单元测试展示了并发转账场景下两种锁的效果,指出在读多写少和写多读少的操作中如何选择合适的锁类型。
摘要由CSDN通过智能技术生成

本文以转账操作为例,实现并测试乐观锁和悲观锁。

死锁问题

当 A, B 两个账户同时向对方转账时,会出现如下情况:

时刻

事务 1 (A 向 B 转账)

事务 2 (B 向 A 转账)

T1

Lock A

Lock B

T2

Lock B (由于事务 2 已经 Lock A,等待)

Lock A (由于事务 1 已经 Lock B,等待)

由于两个事务都在等待对方释放锁,于是死锁产生了,解决方案:按照主键的大小来加锁,总是先锁主键较小或较大的那行数据。

建立数据表并插入数据(MySQL)

create table account

(

id int auto_increment

primary key,

deposit decimal(10, 2) default 0.00 not null,

version int default 0 not null

);

INSERT INTO vault.account (id, deposit, version) VALUES (1, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (2, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (3, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (4, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (5, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (6, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (7, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (8, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (9, 1000, 0);

INSERT INTO vault.account (id, deposit, version) VALUES (10, 1000, 0);

Mapper 文件

悲观锁使用 select ... for update,乐观锁使用 version 字段。

/p>

"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

select *

from account

where id = #{id}

update account

set deposit=#{deposit},

version = version + 1

where id = #{id}

and version = #{version}

select *

from account

where id = #{id} for

update

update account

set deposit=#{deposit}

where id = #{id}

select sum(deposit) from account;

Mapper 接口

@Component

public interface AccountMapper {

Account selectById(int id);

Account selectByIdForUpdate(int id);

i

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值