Redis教程 - Transaction(事务)

2017-04-20  本文已影响122人  FX_SKY

为了保证多条命令组合的原子性,Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。本节首先简单介绍Redis中事务的使用方法,以及它的局限性,之后重点介绍Lua语言的基本使用方法,以及如何将Redis与Lua脚本进行集成。

事务

熟悉关系型数据库的同学应该对事务比较了解,简单的说事务代表一组动作,要么全部执行,要么全部不执行。例如,A给B转账100,首先,从A的账户减100,然后给B的账户加100,这两个行为要么全部执行,要么全部不执行,否则会出现数据不一致的情况。

Redis提供了简单的事务功能,将一组需要一起执行的命令放到multi和exec两个命令直接。multi命名代表事务开始,exec命名代表事务结束,它们之间的命令是原子顺序执行的。

例如:

multi
set a 100
set b 100
exec

只有当exec命令执行后,

如果要停止事务的执行,可以使用discard命令代替exec命令即可。

如果事务执行中间出错,Redis并不支持 回滚功能。

有些应用场景需要在事务之前,确保事务中的key没有被其它客户端修改过,才执行事务,否则不执行(类似乐观锁)。Redis提供了watch命令来解决这类问题。

Jedis Transaction使用

添加maven依赖:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

在Jedis中使用事务,代码如下:

jedis.watch (key1, key2, ...);
Transaction t = jedis.multi();
t.set("foo", "bar");
t.exec();

如果事务包含的方法有返回值,可以这么做:

Transaction t = jedis.multi();
t.set("fool", "bar"); 
Response<String> result1 = t.get("fool");

t.zadd("foo", 1, "barowitch"); 
t.zadd("foo", 0, "barinsky"); 
t.zadd("foo", 0, "barikoviev");
Response<Set<String>> sose = t.zrange("foo", 0, -1);   // get the entire sortedset
t.exec();  // dont forget it

String foolbar = result1.get();  // use Response.get() to retrieve things from a Response
int soseSize = sose.get().size(); // on sose.get() you can directly call Set methods!

// List<Object> allResults = t.exec(); // you could still get all results at once, as before

参考资料

https://github.com/xetorthio/jedis/wiki/AdvancedUsage

上一篇 下一篇

猜你喜欢

热点阅读