Jedis transactions
When we use JDBC to connect to Mysql, we need to start the transaction before executing the SQL statement; in MyBatis, we also need to use openSession() to obtain the session transaction object to perform SQL execution, query and other operations. When our operation on the database is over, the transaction object is responsible for closing the database connection.
Transaction objects are used to manage and perform various database operations. It can turn on and close database connections, execute SQL statements, and roll back error operations.
Our Redis also has transaction management objects, which are located under redis.clients.jedis.Transaction.
Related code for Jedis transactions:
package cn.com.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class Test7 { public static void main(String[] args) { Jedis jedis = new Jedis("192.168.248.129",6379); Transaction transaction=jedis.multi();//Return a transaction control object//Preload the operation to be executed in the transaction object in advance transaction.set("k4", "v4"); transaction.set("k5", "v5"); transaction.exec();//Execute} }Let's check out redis:
Found that the data has been added
We change the value of k4 and the value of k5 to "v44" and "v55", and then add the transaction.discard() statement after the transaction.exec() statement:
package cn.com.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class Test7 { public static void main(String[] args) { Jedis jedis = new Jedis("192.168.248.129",6379); Transaction transaction=jedis.multi();//Return a transaction control object//Preload the operation to be executed in the transaction object in advance transaction.set("k4", "v44"); transaction.set("k5", "v55"); transaction.discard();//Rolling back} }You will find that the data insertion operation is rolled back, and the two values in redis have not been changed:
We simulate a transaction that swipes a credit card once, using redis transactions to handle some logic:
package cn.com.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class TestTransaction { //Simulate credit card consumption and repayment public static void main(String[] args) { TestTransaction t = new TestTransaction(); boolean retValue = t.transMethod(100); if(retValue){ System.out.println("Successful use of credit card consumption!"); }else{ System.out.println("Failed to use of credit card consumption!"); } } /** * In layman's terms, the watch command is to mark a key. If a key is marked, * if the key is modified by someone else before submitting the transaction, the transaction will fail. This situation can usually be tried again in the program*. * * First, mark balance, and then check whether the balance is sufficient. If it is insufficient, cancel the mark without deduction; * If it is sufficient, start the transaction for update operation. * If the key balance is modified by others during this period, an error will be reported when submitting the transaction (exec). * This type of error can usually be caught in the program and then executed again until it is successful. * */ private boolean transMethod(int amount) { System.out.println("You use credit card to advance payment"+amount+"yuan"); Jedis jedis = new Jedis("192.168.248.129",6379); int balance = 1000;//Available balance int debt;//Out of int amtToSubtract = amount;//Real brushing amount jedis.set("balance", String.valueOf(balance)); jedis.watch("balance"); //jedis.set("balance", "1100");//This sentence should not appear. In order to simulate other programs, the entry has been modified. balance = Integer.parseInt(jedis.get("balance")); if(balance < amtToSubtract){//The available balance is less than the actual brushed amount, the transaction is refused jedis.unwatch(); System.out.println("The available balance is insufficient!"); return false; }else{//When the available balance is sufficient, then execute the deduction operation System.out.println("The deduction transaction starts execution..."); Transaction transaction = jedis.multi(); transaction.decrBy("balance",amtToSubtract);//Balance minus the amount of money in amtToSubtract transaction.incrBy("debt", amtToSubtract);//Credit card debt increases the amount of money in amtToSubtract transaction.exec();//Execute transaction balance = Integer.parseInt(jedis.get("balance")); debt = Integer.parseInt(jedis.get("debt")); System.out.println("debt transaction transaction execution end..."); System.out.println("Your available balance:"+balance); System.out.println("You currently owe money:"+debt); return true; } } }This code simulates the user who used a credit card to swipe 100 yuan. At this time, the available balance of the credit card should be reduced by 100 yuan, and the debt of 100 yuan should be increased.
Running results:
Redis results:
Prove that our operation was successful.
The watch command is added to prevent other operations from interrupting transactions or affecting the transaction's calculation results during transaction execution, resulting in abnormal situations such as "illusion reading" and "dirty data". The watch command creates a key. Once it is found that the key has been modified by someone else during execution, the transaction will fail. This type of error can usually be caught in the program and then executed again until it is successful. Therefore, the watch command can ensure the synchronization of data.
In order to prove the purpose of the watch command, we release the jedis.set("balance", "1100"); comment in the above code, and then the transMethod method throws the interrupted exception: throws InterruptedException, the main method catches the interrupted exception, and then a corresponding warning box pops up.
package cn.com.redis; import java.util.List; import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class TestTransaction { //Simulate credit card consumption and repayment public static void main(String[] args) { TestTransaction t = new TestTransaction(); boolean retValue=false; boolean Interrupted = false; try { retValue = t.transMethod(100); } catch (InterruptedException e) { Interrupted = true; System.out.println("The transaction is interrupted, please execute again!"); } finally{ if(retValue){ System.out.println("Successful use of credit card!"); }else{ if(!Interrupted){ System.out.println("Failed to use of credit card! Insufficient balance!"); } } } } } /** * In simple terms, the watch command is to mark a key. If a key is marked, * if the key is modified by someone else before submitting the transaction, the transaction will fail. This situation can usually be tried again in the program*. * * First, mark balance, and then check whether the balance is sufficient. If it is insufficient, cancel the mark without deduction; * If it is sufficient, start the transaction for update operation. * If the key balance is modified by others during this period, an error will be reported when submitting the transaction (exec). * This type of error can usually be caught in the program and then executed again until it is successful. * */ private boolean transMethod(int amount) throws InterruptedException{ System.out.println("You use your credit card to advance payment"+amount+"yuan"); Jedis jedis = new Jedis("192.168.248.129",6379); int balance = 1000;//Available balance int debt;//Absolute amount int amtToSubtract = amount;//Real brush limit jedis.set("balance", String.valueOf(balance)); jedis.watch("balance"); jedis.set("balance", "1100");//This sentence should not appear. In order to simulate other programs, the entry has been modified. balance = Integer.parseInt(jedis.get("balance")); if(balance < amtToSubtract){//The available balance is less than the actual brushed amount, the transaction is refused jedis.unwatch(); System.out.println("The available balance is insufficient!"); return false; }else{//When the available balance is sufficient, then execute the deduction operation System.out.println("The deduction transaction starts execution..."); Transaction transaction = jedis.multi(); transaction.decrBy("balance",amtToSubtract);//The balance minus the money of amtToSubtract transaction.incrBy("debt", amtToSubtract);//The credit card debt increases the money of amtToSubtract List<Object> result = transaction.exec();//The transaction execution if(result==null){//The transaction submission failed, indicating that the data was modified during execution System.out.println("deduct transaction execution interrupt..."); throw new InterruptedException(); }else{//The transaction submission successful balance = Integer.parseInt(jedis.get("balance")); debt = Integer.parseInt(jedis.get("debt")); System.out.println("deduct transaction execution end..."); System.out.println("Your available balance:"+balance); System.out.println("You currently owe money:"+debt); return true; } } } } }Run it again and see the effect:
This shows that if the data is modified after the watch command is executed and before the transaction is submitted, the transaction execution will not be successful, which ensures the security of the data.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.