127.0.0.1:6379>set tony 500
OK
127.0.0.1:6379>set jack 200
OK
127.0.0.1:6379> mget tony jack
1)"500"2)"200"127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379(TX)> decrby tony 100#所有指令操作会进入到队列
QUEUED
127.0.0.1:6379(TX)> incrby jack 100
QUEUED
127.0.0.1:6379(TX)> mget tony jack
QUEUED
127.0.0.1:6379(TX)>exec#提交事务1)(integer)4002)(integer)3003)1)"400"2)"300"127.0.0.1:6379> mget tony jack
1)"400"2)"300"127.0.0.1:6379>
4. discard取消事务
Redis没有事务回滚,只有取消事务
127.0.0.1:6379> mget tony jack
1)"400"2)"300"127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby jack 100
QUEUED
127.0.0.1:6379(TX)> discard
OK
127.0.0.1:6379> get jack
"300"127.0.0.1:6379>exec(error) ERR EXEC without MULTI
127.0.0.1:6379> get jack
"300"127.0.0.1:6379>
当出现错误指令时,事务也会自动取消
127.0.0.1:6379> mget tony jack
1)"400"2)"300"127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby jack 100
QUEUED
127.0.0.1:6379(TX)> sadas
(error) ERR unknown command`sadas`, with args beginning with:
127.0.0.1:6379(TX)> get jack
QUEUED
127.0.0.1:6379(TX)>exec(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get jack
"300"127.0.0.1:6379>
5. 秒杀抢票事务处理
基于一个秒杀抢购案例,演示redis乐观锁方式,例如
打开客户端1,执行如下操作:
127.0.0.1:6379>set ticket 1
OK
127.0.0.1:6379>set money 0
OK
127.0.0.1:6379>watch ticket #乐观锁,对值进行观察,改变则事务失败
OK
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> decr ticket
QUEUED
127.0.0.1:6379> incrby money 100
QUEUED
打开客户端2,执行如下操作,演示还没等客户端1提交事务,此时客户端2把票买到了。
127.0.0.1:6379> get ticket
"1"127.0.0.1:6379> decr ticket
(integer)0
回到客户端1:提交事务,检查ticket的值
127.0.0.1:6379>exec(nil)#执行事务,失败127.0.0.1:6379> get ticket
“0”
127.0.0.1:6379> unwatch #取消监控
java.lang.ArithmeticException:/ by zero
at com.jt.JedisTransactionTests.testTransaction(JedisTransactionTests.java:26)......
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
jack:300
rose:500