Redis之事务
Redis 事务
正常来说,一个可以商用的数据库往往都有比较完善的事务支持,Redis 当然也不例外。相对于 关系型数据库中的事务模型,Redis 中的事务要简单很多。因为简单,所以 Redis 中的事务模型不太严格,所以我们不能像使用关系型数据库中的事务那样来使用 Redis。
在关系型数据库中,和事务相关的三个指令分别是:
- begin
- commit
- rollback
在 Redis 中,当然也有对应的指令:
- multi
- exec
- discard
1.原子性
注意,Redis 中的事务并不能算作原子性。它仅仅具备隔离性,也就是说当前的事务可以不被其他事务打断。
由于每一次事务操作涉及到的指令还是比较多的,为了提高执行效率,我们在使用客户端的时候,可以通过 pipeline 来优化指令的执行。
Redis 中还有一个 watch 指令,watch 可以用来监控一个 key,通过这种监控,我们可以确保在 exec之前,watch 的键的没有被修改过。
2.java代码实现
public class TransactionTest {
public Integer saveMoney(Jedis jedis,String userId, Integer money){
while (true){
//监控userId,如果userId被修改,则重新执行一次
jedis.watch(userId);
System.out.println(jedis.get(userId));
if (jedis.get(userId)!=null){
int v=Integer.parseInt(jedis.get(userId))+money;
Transaction tx = jedis.multi();
tx.set(userId,String.valueOf(v));
List<Object> exec = tx.exec();
if (exec!=null){
break;
}
}else{
jedis.append(userId,"0");
int v=Integer.parseInt(jedis.get(userId))+money;
Transaction tx = jedis.multi();
tx.set(userId,String.valueOf(v));
List<Object> exec = tx.exec();
if (exec!=null){
break;
}
}
}
return Integer.parseInt(jedis.get(userId));
}
public static void main(String[] args) {
new Redis().execute(jedis -> {
new TransactionTest().saveMoney(jedis,"zhong",1000);
System.out.println(jedis.get("zhong"));
});
}
}
浙公网安备 33010602011771号