catalogue
Normal execution of transactions
Monitor} Watch (frequently asked in interview)
Test multithreading to modify the value. Using watch can be used as redis optimistic lock operation
1. Import corresponding dependencies
The transaction executed successfully
redis transaction essence: a set of commands! All commands in a transaction are serialized and executed in sequence during execution
One time, sequential, exclusive, execute some columns of commands
A single redis command maintains atomicity, but transactions do not guarantee atomicity
redis transactions do not have the concept of isolation level
All commands are not executed directly in the transaction. Only the initiated execution command can be executed! Exec
redis transaction
- Open transaction (multi)
- Order to join the team
- Execute transaction (exec)
Normal execution of transactions
127.0.0.1:6379> multi # Will open is a transaction OK # Order to join the team 127.0.0.1:6379(TX)> set k1 v1 QUEUED # QUEUED queue 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> get k1 QUEUED 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> exec # implement 1) OK 2) OK 3) "v1" 4) OK
Abandon transaction
127.0.0.1:6379> multi # Open transaction OK 127.0.0.1:6379(TX)> set k1 v1 QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> DISCARD # Cancel transaction OK 127.0.0.1:6379> get k3 # None of the commands in the transaction queue will be executed (nil)
Compiled exception
There is a problem with the code and the command. All commands in the transaction will not be executed
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set k1 v1 QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> setget k4 v4 # Wrong command (error) ERR unknown command `setget`, with args beginning with: `k4`, `v4`, 127.0.0.1:6379(TX)> set k5 v5 QUEUED 127.0.0.1:6379(TX)> exec # Error in executing transaction (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get k5 # All commands will not be executed (nil)
Runtime exception (I/O)
(other commands are executed normally, and the error command throws an exception)
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> incr k1 # When an error occurs during execution, incr can only be self incremented. The number type cannot be String type QUEUED 127.0.0.1:6379(TX)> set k2 v2 QUEUED 127.0.0.1:6379(TX)> set k3 v3 QUEUED 127.0.0.1:6379(TX)> get k3 QUEUED 127.0.0.1:6379(TX)> exec 1) (error) ERR value is not an integer or out of range # Although the first command reported an error, it was still executed normally and successfully 2) OK 3) OK 4) "v3" 127.0.0.1:6379> get k2 "v2" 127.0.0.1:6379> get k3 "v3"
Monitor} Watch (frequently asked in interview)
Pessimistic lock: very pessimistic, thinking that problems will occur at any time, lock everything, and reduce efficiency
Optimistic lock:
- I'm optimistic that there will be no problem at any time, so I don't lock it. When updating the data, I will judge whether someone has changed the data during this period. version!
- Get version
- Compare version when updating
redis monitoring test
Normal execution succeeded!
127.0.0.1:6379> set money 100 OK 127.0.0.1:6379> set out 0 OK 127.0.0.1:6379> watch money # Monitor money objects OK 127.0.0.1:6379> multi # The transaction ends normally and there is no change in the data period. At this time, the normal execution is successful OK 127.0.0.1:6379(TX)> DECRBY money 20 QUEUED 127.0.0.1:6379(TX)> INCRBY out 20 QUEUED 127.0.0.1:6379(TX)> exec 1) (integer) 80 2) (integer) 20
Test multithreading to modify the value. Using watch can be used as redis optimistic lock operation
Thread one
127.0.0.1:6379> watch money # Monitor money OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> decrby money 10 QUEUED 127.0.0.1:6379(TX)> incrby out 10 QUEUED 127.0.0.1:6379(TX)> exec # Before execution, another thread modifies our value. At this time, it will (nil) Cause transaction execution failure
Thread two
127.0.0.1:6379> get money "80" 127.0.0.1:6379> set money 1000 OK
At this point, the thread wants to continue the operation
127.0.0.1:6379(TX)> exec (nil) 127.0.0.1:6379> unwatch # 1. If the transaction fails to execute, unlock it first OK 127.0.0.1:6379> watch money # 2. Get the latest value, which is similar to MySql select version in this monitoring OK 127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> decrby money 10 QUEUED 127.0.0.1:6379(TX)> incrby money 10 QUEUED 127.0.0.1:6379(TX)> exec # Compare whether the monitored value has changed. If there is no change, it can be executed successfully 1) (integer) 990 If there is a change, the execution fails 2) (integer) 1000
Jedis
We should use java to operate redis. We should know its nature and why
Jedis is an officially recommended Java connection development tool, which uses Java to operate redis middleware. If you want to use java to operate redis, you must be very familiar with jedis
Test:
1. Import corresponding dependencies
<!--Import jedis My bag--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.2.0</version> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> </dependency>
2. Coding test:
- Link redis
- Operation command
- break link
Open port 6379 firewall-cmd --permanent --zone=public --add-port=6379/tcp --permanent Restart firewall service systemctl restart firewalld.service restart redis-server redis-server gconfig/redis.conf
public class RedisTest { public static void main(String[] args) { //1. New jedis object Jedis jedis = new Jedis("127.0.0.1",6379); //All the commands of Jedis are all the commands we learned before System.out.println(jedis.ping()); } }
Output:
Redis -Key
/** * @author gh Email:@2495140780qq.com * @Description * @date 2022-03-04-11:54 am */ public class TestKey { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1",6379); System.out.println("Clear the data in the specified database:" + jedis.flushDB()); System.out.println("Clear all data:" + jedis.flushAll()); System.out.println("newly added<'username','zhangsan'>Key value pairs:" + jedis.set("username","zhangsan")); System.out.println("newly added<'password','123456'>Key value pairs:" + jedis.set("password","123456")); System.out.print("All keys in the system are as follows:"); Set<String> keys = jedis.keys("*"); System.out.println(keys); System.out.println("Delete key password: " + jedis.del("password")); System.out.println("Judgment key password Is there:" + jedis.exists("password")); System.out.println("View key username The type of value stored" + jedis.type("username")); System.out.println("Random return key A of space" + jedis.randomKey()); System.out.println("rename key: " + jedis.rename("username","userName")); System.out.println("Take out the modified userName: " + jedis.get("userName")); System.out.println("Query by index:" + jedis.select(0)); System.out.println("Return to the current database key Quantity of:" + jedis.dbSize()); System.out.println("Delete all in the currently selected database key: " + jedis.flushDB()); System.out.println("Return to the current database key Quantity of:" + jedis.dbSize()); System.out.println("Delete all that in all databases key: " + jedis.flushAll()); } }
Redis -String
/** * @author gh Email:@2495140780qq.com * @Description * @date 2022-03-04-12:06 PM */ public class TestString { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.flushDB(); System.out.println(" ===========Add data ==========="); System.out.println(jedis.set("key1", "value1")); System.out.println(jedis.set("key2", "value2")); System.out.println(jedis.set("key3", "value3")); System.out.println("Delete key key2:" + jedis.del("key2")); System.out.println("Get key key2:" + jedis.get("key2")); System.out.println("modify key1:" + jedis.set("key1", "value1Changed")); System.out.println("obtain key1 Value of:" + jedis.get("key1")); System.out.println("stay key3 Add value after:" + jedis.append("key3", "End")); System.out.println("key3 Value of:" + jedis.get("key3")); System.out.println("Add multiple key value pairs:" + jedis.mset("key01", "value01", "key02", "value02", "key03", "values03")); System.out.println("Get multiple key value pairs:" + jedis.mget("key01", "key02", "key03")); System.out.println("Get multiple key value pairs:" + jedis.mget("key01", "key02", "key03", "key04")); System.out.println(" Delete multiple key value pairs:" + jedis.del("key01", " key02")); System.out.println(" Get multiple key value pairs:" + jedis.mget("key01", "key02", "key03")); jedis.flushDB(); System.out.println("===========Adding a key value pair prevents overwriting the original value=========="); System.out.println(jedis.setnx("key1", "value1")); System.out.println(jedis.setnx("key2", "value2")); System.out.println(jedis.setnx("key2", "value2-new")); System.out.println(jedis.get("key1")); System.out.println(jedis.get("key2")); System.out.println("===========Add key value pairs and set effective time============="); System.out.println(jedis.setex("key3", 2, "value3")); System.out.println(jedis.get("key3")); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); System.out.println(jedis.get("key3")); System.out.println("===========Get the original value and update it to the new value=========="); System.out.println(jedis.getSet("key2", "key2GetSet")); System.out.println(jedis.get("kev2")); System.out.println("get key2 String of values:" + jedis.getrange("key2", 2, 4)); } } }
Redis-List
/** * @author gh Email:@2495140780qq.com * @Description * @date 2022-03-04-12:28 PM */ public class TestList { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.flushDB(); System.out.println("=========Add a list========"); jedis.lpush("collections", "ArrayList", "Vector", "Stack", "HashMap", "WeakHashMap", "LinkedHashmap"); jedis.lpush("collections", "Hashset"); jedis.lpush("collections", "TreeSet"); jedis.lpush("collections", "TreeMap"); System.out.println("collections Content of : "+jedis.lrange("collections", 0 , -1)); System.out.println("collections Interval 0 -3 Content of : "+jedis.lrange("collections", 0 , 3)); System.out.println("======================"); //Delete the value specified in the list. The second parameter is the number of deleted values (when there are duplicates). The value add ed later is deleted first, which is similar to out of the stack System.out.println("Deletes the specified element:" + jedis.lrem("collections",2,"HashMap")); System.out.println("collections Content of : "+jedis.lrange("collections", 0 , -1)); System.out.println("collections Interval 0 -3 Content of : "+jedis.lrange("collections", 0 , 3)); System.out.println("collections List out of stack (left end) : "+jedis.lpop("collections")); System.out.println("collections Content of : "+jedis.lrange("collections", 0 , -1)); System.out.println("collections Add elements, from the right end of the list rpush : "+jedis.rpush("collections", "EnumMap")); System.out.println("collections Content of : "+jedis.lrange("collections", 0 , -1)); System.out.println("collections List out of stack (right end) : "+jedis.rpop("collections")); System.out.println("collections Content of : "+jedis.lrange("collections", 0 , -1)); System.out.println("modify collections Specifies the contents of subscript 1:" + jedis.lset("collections",1,"LinkArrayList")); System.out.println("collections Content of : "+jedis.lrange("collections", 0 , -1)); System.out.println("============================="); System.out.println("collections Length of : "+jedis.llen("collections")); System.out.println("obtain collections Specifies the contents of subscript 2:" + jedis.lindex("collections",2)); System.out.println("============================="); jedis.lpush("sortedList", "3", "6", "2", "0", "7", "4"); System.out.println("sortedList Before sorting" + jedis.lrange("sortedList",0,-1)); System.out.println(jedis.sort("sortedList")); System.out.println("sortedList After sorting" + jedis.lrange("sortedList",0,-1)); } }
affair
The transaction executed successfully
/** * @author gh Email:@2495140780qq.com * @Description * @date 2022-03-04-2:30 PM */ public class TestTx { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1",6379); jedis.flushDB(); JSONObject jsonObject = new JSONObject(); jsonObject.put("name", "zhangsan"); jsonObject.put("age", 15); String result = jsonObject.toString(); Transaction multi = jedis.multi();//Open transaction try { multi.set("user1", result); multi.set("user2", result); multi.exec();//Execute transaction } catch (Exception e) { //If an exception occurs, the transaction is abandoned multi.discard(); e.printStackTrace(); } finally { System.out.println(jedis.get("user1")); System.out.println(jedis.get("user2")); jedis.close();//Close link } } }
Exception in transaction
/** * @author gh Email:@2495140780qq.com * @Description * @date 2022-03-04-2:30 PM */ public class TestTx { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1",6379); jedis.flushDB(); JSONObject jsonObject = new JSONObject(); jsonObject.put("name", "zhangsan"); jsonObject.put("age", 15); String result = jsonObject.toString(); Transaction multi = jedis.multi();//Open transaction try { multi.set("user1", result); multi.set("user2", result); int i = 1 / 0; //Manufacturing exception multi.exec();//Execute transaction } catch (Exception e) { //If an exception occurs, the transaction is abandoned multi.discard(); e.printStackTrace(); } finally { System.out.println(jedis.get("user1")); System.out.println(jedis.get("user2")); jedis.close();//Close link } } }