Spring+Redis事务处理

一、概述

很多数据库都涉及到事务的处理,当然Redis也有事务的处理。Redis中的事务是一组命令集合,及事务队列,队列中的命令要么全部执行,要么都不执行。这些命令是我们在调用EXEC函数后全部执行的。
二、Spring中具体实现

在Spring中我们要实现Redis事务,依然需要使用到RedisTemplate这个工具类。
具体实现如下:
 
 
ListOperations<String,Object> listOperations = redisTemplate.opsForList();
        redisTemplate.setEnableTransactionSupport(true);

        String userOneFollowing = "user:1:following";
        String userOneFollowers = "user:1:followers";
        String userTwoFollowing = "user:2:following";
        String userTwoFollowers = "user:2:followers";
        //开始事务
        redisTemplate.multi();
        listOperations.leftPush(userOneFollowing,"two");
        listOperations.leftPush(userOneFollowers,"two");

        System.out.println(listOperations.leftPop(userOneFollowers));
//        int i = 1/0;
        listOperations.leftPush(userTwoFollowing,"one");
        listOperations.leftPush(userTwoFollowers,"one");

        //提交事务
        System.out.println(redisTemplate.exec());

        System.out.println(listOperations.leftPop(userOneFollowing));
        listOperations.remove(userOneFollowing,1,1000);


执行命令后,我们可以看见如下输出:
null
[4, 11, two, 14, 14]
two

当我们取消代码中int i = 1/0处的注释的时候,我们可以发现输出如下:

null

java.lang.ArithmeticException: / by zero

	at RedisTransactionalTest.testTransactional(RedisTransactionalTest.java:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)

可以看见上面的事务中的操作都没有进行。
三、WATCH命令

在我们进行操作的时候,可能涉及到你获取的数据的值,在你使用其进行其他操作的过程中被其他线程给修改了,也就是存在竟态问题,这个时候就需要使用WATCH关键字来进行解决了,在我们针对某一key进行WATCH过后,如果这个key在事务执行前被修改了,事务就不会执行。
具体使用如下:
//WATCH的使用,注意也可以使用UNWATCH来取消监控
        ValueOperations<String,Object> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("name","zhangsan");
        redisTemplate.watch("name");
        valueOperations.set("name","lisi");
        redisTemplate.multi();
        valueOperations.set("name","wahaha");
        redisTemplate.exec();
        System.out.println(valueOperations.get("name"));
输出结果:
 
 
lisi
我们可以看见事务中的语句并没有执行。
四、总结
源码地址: 点击打开链接


猜你喜欢

转载自blog.csdn.net/ONROAD0612/article/details/80053498