说明
每个连接都对应一个ID变量,每个连接的操作只影响本连接的变量。在一些场景中可以直接查询出ID变量的值,而不是去查询真实数据库的表。
- 更新ID变量
- 向主键自增的表插入一条数据
update sequence set id = LAST_INSERT_ID(id + 1);
- 查询ID变量
通过SELECT LAST_INSERT_ID()
查询。
一般通过下面用法返回刚刚插入数据生成的自增主键。
<insert id="ItemTable.addItem" parameterClass="itemDO">
insert into
item_table (<include refid="itemDO.all_field_no_id" />)
values(#itemTitle#, #itemPrice#)
<selectKey keyProperty="id" resultClass="java.lang.Long" >
SELECT LAST_INSERT_ID() AS value
</selectKey>
</insert>
应用举例之 - tddl-sequence
乐观锁实现方式
该方式会发生不断的自旋,从而影响吞吐量。但是,下面的三个sql没必要在一个事务中。
- 先从数据库查询当前的最大 ID
select value as old_value form sequence_table where name = 'mySequence'
- 根据最大 ID 算出更新后的ID
long newValue = oldValue + 1;
使用乐观锁锁更新数据库 ID,如果乐观锁失败则从第一步重新开始 update sequence_table set value = new_value where name = 'mySequence' and value = old_value
LAST_INSERT_ID实现
tddl采取的是这种方式,该方式下,下面两个步骤必须在一个事务中。从本实现中可以体会LAST_INSERT_ID带来的好处-不用查询真正的表。
- 直接更新 ID 并将更新后的值记录到 last_insert_id 中
update sequence_table set value = last_insert_id( value + 1 ) where name = 'mySequence'
SELECT LAST_INSERT_ID()