-
Notifications
You must be signed in to change notification settings - Fork 447
Java客户端 乐观锁
Since:1.6.0
Version用于乐观锁更新。当更新操作执行的时候,version对应的字段会作为查询条件与主键一起包含在update语句里面。只有当version字段的值与数据库里面version值一致的情况下,更新才能成功
适用于单表DAO里面的update和batchUpdate更新操作。
当前不支持携程的SqlServer,因为现在携程的SqlServer是通过SPA/SP3的方式来执行CUD操作。
支持通过标注@Version作为表的版本字段。支持整形和时间戳类型。一个entity只能定义一个版本字段。
如果没有指定version字段不能更新,则在更新的时候DAL会自动更新版本。整形为加1操作,时间戳为获取数据库的时间戳 @Column(name="last_changed") @Type(value=Types.TIMESTAMP) @Version private Timestamp lastChanged;
如果数据库本身设置了更新的触发器能自动更新版本自动,则可以通过指定@Column里面的updatable=false来取消自动更新。 @Column(name="version", updatable=false) @Type(value=Types.INTEGER) @Version private Integer version;
如果希望插入的时候也使用数据库的缺省值或触发器,可以通过指定@Column里面的insertable=false来在插入操作中去掉version字段。否则需要用户自己给版本赋值 @Column(name="last_changed", insertable=false) @Type(value=Types.INTEGER) @Version private Integer version;
第一个是基于时间戳的,第二个是基于int的
注意:例子是直接调用的底层API,目的只是验证版本是否起效。实际运行时只用通过生成的dao里面的batchUpdate或update来完成即可
@Test
public void testUpdatableWithVersion() throws SQLException {
BatchUpdateTask<UpdatableVersionModel> test = new BatchUpdateTask<>();
DalParser<UpdatableVersionModel> parser = new DalDefaultJpaParser<>(UpdatableVersionModel.class, getDbName());
test.initialize(parser);
DalTableDao<UpdatableVersionModel> dao = new DalTableDao<UpdatableVersionModel>(parser);
DalHints hints = new DalHints();
List<UpdatableVersionModel> pojos = dao.query("1=1", new StatementParameters(), new DalHints());
long[] oldVer = new long[3];
int i = 0;
for(UpdatableVersionModel model: pojos){
model.setAddress("1122334455");
oldVer[i++] = model.getLastChanged().getTime();
}
int[] result = test.execute(hints, test.getPojosFieldsMap(pojos));
assertArrayEquals(new int[]{1, 1, 1}, result);
pojos = dao.query("1=1", new StatementParameters(), new DalHints());
i = 0;
for(UpdatableVersionModel model: pojos){
assertEquals("1122334455", model.getAddress());
Assert.assertTrue(oldVer[i++] <= model.getLastChanged().getTime());
}
}
@Test
public void testUpdatableWithIntVersion() throws SQLException {
BatchUpdateTask<UpdatableIntVersionModel> test = new BatchUpdateTask<>();
DalParser<UpdatableIntVersionModel> parser = new DalDefaultJpaParser<>(UpdatableIntVersionModel.class, getDbName());
test.initialize(parser);
DalTableDao<UpdatableIntVersionModel> dao = new DalTableDao<>(parser);
DalHints hints = new DalHints();
Integer[] oldValue = new Integer[3];
List<UpdatableIntVersionModel> pojos = dao.query("1=1", new StatementParameters(), new DalHints());
int i = 0;
for(UpdatableIntVersionModel model: pojos){
model.setAddress("1122334455");
oldValue[i++] = model.getTableIndex();
}
int[] result = test.execute(hints, test.getPojosFieldsMap(pojos));
assertArrayEquals(new int[]{1, 1, 1}, result);
pojos = dao.query("1=1", new StatementParameters(), new DalHints());
i = 0;
for(UpdatableIntVersionModel model: pojos) {
assertEquals("1122334455", model.getAddress());
Assert.assertTrue(oldValue[i++]+1 == model.getTableIndex());
}
}