mybatis mysql 乐观锁_基于tx.mapper实现的mysql乐观锁

1.表CREATE TABLE `demo` (

`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '物理主键',

`demo_id` varchar(32) NOT NULL COMMENT '业务主键',

`demo_name` varchar(255) DEFAULT NULL COMMENT '名称',

`total_num` int(11) DEFAULT NULL COMMENT '数字',

`version` bigint(20) DEFAULT '0' COMMENT '版本号:乐观锁专用',

`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

PRIMARY KEY (`id`),

UNIQUE KEY `demo_id` (`demo_id`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='测试专用表';

ps:version字段必不可少,我这里用的数值类型,可统计数据更新评率

2.代码

默认支持delete

deleteByPrimaryKey

updateByPrimaryKey

updateByPrimaryKeySelective

updateByExample

updateByExampleSelective

实体:@Getter

@Setter

@Table(name = "`demo`")

public class Demo extends BaseBean {

private static final long serialVersionUID = -5862829001800404154L;

/**

* 物理主键

*/

@Id

@Column(name = "`id`")

@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SELECT LAST_INSERT_ID()")

private Long id;

/**

* 业务主键

*/

@Column(name = "`demo_id`")

private String demoId;

/**

* 名称

*/

@Column(name = "`demo_name`")

private String demoName;

/**

* 数字

*/

@Column(name = "`total_num`")

private Integer totalNum;

/**

* 版本号:乐观锁专用

*/

@Column(name = "`version`")

@Version

private Long version;

/**

* 创建时间

*/

@Column(name = "`create_time`")

private Date createTime;

/**

* 更新时间

*/

@Column(name = "`update_time`")

private Date updateTime;

}

ps:以下是tk.mapper的源码,可见默认支持int和long以及时间戳类型,当然如果需要自定义,实现该接口即可// 版本字段标识的注解

@tk.mybatis.mapper.annotation.version

//实现接口

tk.mybatis.mapper.version.NextVersion

//默认实现策略

tk.mybatis.mapper.version.DefaultNextVersion

//源码例子

public class DefaultNextVersion implements NextVersion {

public DefaultNextVersion() {

}

public Object nextVersion(Object current) throws VersionException {

if (current == null) {

throw new VersionException("当前版本号为空!");

} else if (current instanceof Integer) {

return (Integer)current + 1;

} else if (current instanceof Long) {

return (Long)current + 1L;

} else if (current instanceof Timestamp) {

return new Timestamp(System.currentTimeMillis());

} else {

throw new VersionException("默认的 NextVersion 只支持 Integer, Long 和 java.sql.Timestamp 类型的版本号,如果有需要请自行扩展!");

}

}

}

3.测试@Slf4j

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest(classes = Main.class)

public class VersionTest{

@Autowired

private DemoMapper demoMapper;

@Autowired

private ThreadPoolTaskExecutor taskExecutor;

private Long id;

@Before

public void before() {

Demo demo = new Demo();

demo.setDemoId(AppUtils.getUUID19());

demo.setDemoName("测试一号");

demo.setTotalNum(RandomUtils.nextInt(0, 100000));

demoMapper.insertSelective(demo);

id = demo.getId();

}

@Test

public void insert() {

Demo demo = demoMapper.selectByPrimaryKey(id);

demo.setTotalNum(RandomUtils.nextInt(0, 100000));

demoMapper.updateByPrimaryKey(demo);

}

@Test

public void multiThread() {

for (int i = 0; i < 20; i++) {

int finalI = i;

taskExecutor.execute(() -> {

Demo demo = demoMapper.selectByPrimaryKey(id);

demo.setTotalNum(finalI);

log.info("第{}次修改结果:{}", finalI, demoMapper.updateByPrimaryKey(demo));

});

}

}

@After

public void after() throws InterruptedException {

Thread.sleep(10 * 1000);

log.info("运行结束");

}

}

测试结果:DEBUG [main] insertSelective:159- ==> Preparing: INSERT INTO `demo` ( `id`,`demo_id`,`demo_name`,`total_num` ) VALUES( ?,?,?,? )

DEBUG [main] insertSelective:159- ==> Parameters: null, HTNGBUKRSUDSJEJ5M7K(String), 测试N号(String), 68031(Integer)

DEBUG [main] insertSelective:159- <== Updates: 1

DEBUG [main] insertSelective!selectKey:159- ==> Executing: SELECT LAST_INSERT_ID()

DEBUG [main] insertSelective!selectKey:159- <== Total: 1

DEBUG [main] selectByPrimaryKey:159- ==> Preparing: SELECT `id`,`demo_id`,`demo_name`,`total_num`,`version`,`create_time`,`update_time` FROM `demo` WHERE `id` = ?

DEBUG [main] selectByPrimaryKey:159- ==> Parameters: 5(Long)

DEBUG [main] selectByPrimaryKey:159- <== Total: 1

DEBUG [main] updateByPrimaryKey:159- ==> Preparing: UPDATE `demo` SET `demo_id` = ?,`demo_name` = ?,`total_num` = ?,`version` = ?,`create_time` = ?,`update_time` = ? WHERE `id` = ? AND `version` = ?

DEBUG [main] updateByPrimaryKey:159- ==> Parameters: HTNGBUKRSUDSJEJ5M7K(String), 测试N号(String), 54481(Integer), 1(Long), 2019-08-23 09:04:39.0(Timestamp), 2019-08-23 09:04:39.0(Timestamp), 5(Long), 0(Long)

DEBUG [main] updateByPrimaryKey:159- <== Updates: 1

INFO [main] VersionTest:58- 运行结束

ps:Main类是我springboot的启动类,当然了,这里是基于springboot工程做的测试

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值