springboot redis使用之redis事務(wù)

保持自信

redis也是有它的事務(wù)支持的,我們來看看在springboot中如何使用redis的事務(wù)特性吧

方法一

首先在redis的配置類中開啟事務(wù)支持

template.setEnableTransactionSupport(true);

 @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        //開啟事務(wù)支持
        template.setEnableTransactionSupport(true);
        return template;
    }

驗(yàn)證如下

  • redisTemplate.multi(); 開啟事務(wù)
  • redisTemplate.exec(); 提交事務(wù)
  • redisTemplate.discard(); 回滾事務(wù)
package com.springboot.study.demo1;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;
/**
 *@description: Test1
 *@author: yinkai
 *@create: 2020/3/7 21:15
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ValueOperations<String, String> valueOperations;
    @org.junit.Test
    public void set() {
        //收集命令然后在 exec()時(shí)執(zhí)行,不同于mysql這種關(guān)系型數(shù)據(jù)庫
        try {
            //開啟事務(wù)
            redisTemplate.multi();
            valueOperations.set("t1", "hello ");
            int i = 1 / 0;
            valueOperations.set("t2", "world ");
            //提交事務(wù)
            redisTemplate.exec();
        }catch (Exception e){
            //取消執(zhí)行事務(wù)
            redisTemplate.discard();
        }
    }
}

執(zhí)行后可以發(fā)現(xiàn),因?yàn)槌霈F(xiàn)除0異常。redis并沒有插入數(shù)據(jù)。那redis事務(wù)的原理是什么呢?
只是把事務(wù)內(nèi)所有的redis操作收集起來,在redisTemplate.exec(); 提交事務(wù)時(shí)一起執(zhí)行而已,并不是像mysql這種關(guān)系型數(shù)據(jù)庫一樣把每條sql都執(zhí)行了只是沒有持久化

方法二

這種形式我開始以為是異步執(zhí)行的,就像 jQuery 的ajax請(qǐng)求一樣。其實(shí)只是寫法上的改變。redisTemplate.execute方法的返回值只是一個(gè)普通的List,并沒有什么異步獲取結(jié)果的功能。其實(shí)只是寫法上和方法一不同而已,也沒什么優(yōu)勢(shì)啊。不過使用這種方式就不需要在redis配置類中開啟事務(wù)配置了

package com.springboot.study.demo1;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 *@description: Test1
 *@author: yinkai
 *@create: 2020/3/7 21:15
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ValueOperations<String, String> valueOperations;
    @org.junit.Test
    public void set() {

        //execute a transaction
        List<Object> txResults = redisTemplate.execute(new SessionCallback<List<Object>>() {
            public List<Object> execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                valueOperations.set("t1", "hello ");
//                int i = 1 / 0;
                valueOperations.set("t2", "world ");

                return operations.exec();
            }
        });
        System.out.println("Number of items added to set: " + txResults.get(0));

    }
}

關(guān)于 redisTemplate.execute的返回值是個(gè)List,其實(shí)就是execute方法內(nèi)的所有redis操作語句的返回值集合。上面發(fā)出了2條語句。那么這個(gè)list就有2個(gè)元素了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容