mybatis mysql 乐观锁_基于tx.mapper实现的mysql乐观锁
1.表CREATE TABLE `demo` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '物理主鍵',
`demo_id` varchar(32) NOT NULL COMMENT '業(yè)務(wù)主鍵',
`demo_name` varchar(255) DEFAULT NULL COMMENT '名稱',
`total_num` int(11) DEFAULT NULL COMMENT '數(shù)字',
`version` bigint(20) DEFAULT '0' COMMENT '版本號:樂觀鎖專用',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
`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字段必不可少,我這里用的數(shù)值類型,可統(tǒng)計數(shù)據(jù)更新評率
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;
/**
* 業(yè)務(wù)主鍵
*/
@Column(name = "`demo_id`")
private String demoId;
/**
* 名稱
*/
@Column(name = "`demo_name`")
private String demoName;
/**
* 數(shù)字
*/
@Column(name = "`total_num`")
private Integer totalNum;
/**
* 版本號:樂觀鎖專用
*/
@Column(name = "`version`")
@Version
private Long version;
/**
* 創(chuàng)建時間
*/
@Column(name = "`create_time`")
private Date createTime;
/**
* 更新時間
*/
@Column(name = "`update_time`")
private Date updateTime;
}
ps:以下是tk.mapper的源碼,可見默認支持int和long以及時間戳類型,當(dāng)然如果需要自定義,實現(xiàn)該接口即可// 版本字段標識的注解
@tk.mybatis.mapper.annotation.version
//實現(xiàn)接口
tk.mybatis.mapper.version.NextVersion
//默認實現(xiàn)策略
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("當(dāng)前版本號為空!");
} 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("第{}次修改結(jié)果:{}", finalI, demoMapper.updateByPrimaryKey(demo));
});
}
}
@After
public void after() throws InterruptedException {
Thread.sleep(10 * 1000);
log.info("運行結(jié)束");
}
}
測試結(jié)果: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- 運行結(jié)束
ps:Main類是我springboot的啟動類,當(dāng)然了,這里是基于springboot工程做的測試
總結(jié)
以上是生活随笔為你收集整理的mybatis mysql 乐观锁_基于tx.mapper实现的mysql乐观锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2002无法连接mysql阿里云_200
- 下一篇: mysql 5.5 5.6 主从_mys