SpringBoot整合整合MyBatis实现乐观锁和悲观锁的示例实现乐观锁和悲观锁的示例
主要介绍了SpringBoot整合MyBatis实现乐观锁和悲观锁的示例,文中通过示例代码介绍的非常详细,对大家的
学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
本文以转账操作为例,实现并测试乐观锁和悲观锁。
全部代码:https://github.com/imcloudfloating/Lock_Demo
GitHub Page:https://cloudli.top
死锁问题死锁问题
当 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 字段。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cloud.demo.mapper.AccountMapper">
<select id="selectById" resultType="com.cloud.demo.model.Account">
select *
from account
where id = #{id}
</select>
<update id="updateDeposit" keyProperty="id" parameterType="com.cloud.demo.model.Account">
update account
set deposit=#{deposit},
version = version + 1
where id = #{id}
and version = #{version}
</update>
<select id="selectByIdForUpdate" resultType="com.cloud.demo.model.Account">
select *
from account
where id = #{id} for
update
</select>
<update id="updateDepositPessimistic" keyProperty="id" parameterType="com.cloud.demo.model.Account">
update account
set deposit=#{deposit}
where id = #{id}