Spring+Redis transaction processing

I. Overview

Many databases involve transaction processing, and of course Redis also has transaction processing. A transaction in Redis is a set of commands and a transaction queue. The commands in the queue are either all executed or none of them are executed. These commands are all executed after we call the EXEC function.
Second, the specific implementation in Spring

In Spring, if we want to implement Redis transactions, we still need to use the RedisTemplate tool class.
The specific implementation is as follows:
 
 
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";
        // start transaction
        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");

        // commit the transaction
        System.out.println(redisTemplate.exec());

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


After executing the command, we can see the following output:
null
[4, 11, two, 14, 14]
two

When we uncomment int i = 1/0 in the code, we can find the output as follows:

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)

It can be seen that none of the operations in the above transaction are performed.
3. WATCH command

When we operate, it may involve the value of the data you obtained, which is modified by other threads in the process of using it to perform other operations, that is, there is a race problem. At this time, you need to use the WATCH keyword to Solved, after we WATCH a key, if the key is modified before the transaction is executed, the transaction will not be executed.
The specific use is as follows:
//The use of WATCH, note that you can also use UNWATCH to cancel monitoring
        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"));
Output result:
 
 
lysis
We can see that the statements in the transaction are not executed.
4. Summary
Source address: click to open the link


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324694081&siteId=291194637