redis 事务处理,一旦异常,则回滚
事务操作: RedisTemplate
支持事务操作,您可以使用multi()
、exec()
和discard()
来开启、提交或取消事务。
于是使用
/** * redis事务测试 * @author 陈惟鲜 * @date 2023年6月10日 下午2:07:03 * @throws Exception */ @Test public void redis_transaction_test2() throws Exception { String pattern = "test:"; try { // 事务开启 redisTemplate.multi(); redisTemplate.opsForValue().set(pattern + "aa", "aa123456"); redisTemplate.opsForValue().set(pattern + "bb", "bb123456"); // 异常 System.out.println(5 / 0); // 事务提交 redisTemplate.exec(); } catch (Exception e) { // 事务回滚 redisTemplate.discard(); e.printStackTrace(); } }
这样执行会异常,但是事务并未回滚,
提交事务,提示
org.springframework.dao.InvalidDataAccessApiUsageException: No ongoing transaction; Did you forget to call multi at org.springframework.data.redis.connection.jedis.JedisConnection.exec(JedisConnection.java:466) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.data.redis.core.CloseSuppressingInvocationHandler.invoke(CloseSuppressingInvocationHandler.java:61) at jdk.proxy2/jdk.proxy2.$Proxy695.exec(Unknown Source)
修改为下面方式出现异常,能正常回滚
/** * redis事务测试 * @author 陈惟鲜 * @date 2023年6月10日 下午2:07:03 * @throws Exception */ @Test public void redis_transaction_test() throws Exception { String pattern ="test:"; try { // 使用sessionCallBack处理 SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() { List<Object> exec = null; @Override @SuppressWarnings("unchecked") public Boolean execute(RedisOperations operations) throws DataAccessException { operations.multi(); redisTemplate.opsForValue().set(pattern+"cc", "aa123456"); redisTemplate.opsForValue().set(pattern+"dd", "bb123456"); exec = operations.exec(); if(exec.size() > 0) { return (Boolean) exec.get(0); } return false; } }; System.out.println(5/0); redisTemplate.execute(sessionCallback); }catch(Exception e) { e.printStackTrace(); // 事务回滚 redisTemplate.discard(); } }