手動開啟hibernate的事務(wù)的問題

問題代碼(監(jiān)聽redis過期的key)

package com.aaa.bbb.listen;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.transaction.Transactional;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.aaa.bbb.common.Exceptions;
import com.aaa.bbb.common.SpringContextHolder;
import com.aaa.bbb.dao.util.Daoutil;

public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    private static final Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListener.class);
    @Autowired
    private Daoutil daoutil;

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
    /**
     *
     * 監(jiān)聽redis過期失效的key
     */
    @Override
    public void onMessage(Message message, byte[] pattern){
        //手動開啟hibernate的事務(wù)
        HibernateTransactionManager transactionManager = SpringContextHolder.getBean("txManager");
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔離級別,開啟新事務(wù),這樣會比較安全些。
        TransactionStatus status = transactionManager.getTransaction(def); // 獲得事務(wù)狀態(tài)
        String redisKey = message.toString();
        logger.info("即將要失效的Key:" + redisKey);
        //System.out.println("即將要失效的Key:" + redisKey);
        if (StringUtils.isNotBlank(redisKey)) {
            String countSql = "select count(*) from slogintbl where tradeno =? ";
            List<String> countParams = new ArrayList<>();
            countParams.add(redisKey);
            try {
                int count = daoutil.queryCountSql(countSql, countParams);
                if (0 == count) {
                    return;//這里return了,導(dǎo)致問題。
                } else {
                    List<String> params = new ArrayList<>();
                    SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd HH:mm:ss");
                    
                    params.add(sf.format(new Date()));
                    params.add(redisKey);
                    String sql = "update slogintbl set logoutdate=? where tradeno=?";
                    daoutil.updateOrSaveSql(sql, params);
                    transactionManager.commit(status);

                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                logger.debug(Exceptions.getStackTraceAsString(e));
                transactionManager.rollback(status);
            }

        }
    }
}

結(jié)果

沒有關(guān)閉資源導(dǎo)致連接池耗盡

解決方式

  • 方式一
package com.aaa.bbb.listen;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.transaction.Transactional;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.aaa.bbb.common.Exceptions;
import com.aaa.bbb.common.SpringContextHolder;
import com.aaa.bbb.dao.util.Daoutil;

public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    private static final Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListener.class);
    @Autowired
    private Daoutil daoutil;

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
    /**
     *
     * 監(jiān)聽redis過期失效的key
     */
    @Override
    public void onMessage(Message message, byte[] pattern){
        //手動開啟hibernate的事務(wù)
        HibernateTransactionManager transactionManager = SpringContextHolder.getBean("txManager");
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔離級別,開啟新事務(wù),這樣會比較安全些。
        TransactionStatus status = transactionManager.getTransaction(def); // 獲得事務(wù)狀態(tài)
        String redisKey = message.toString();
        logger.info("即將要失效的Key:" + redisKey);
        //System.out.println("即將要失效的Key:" + redisKey);
        if (StringUtils.isNotBlank(redisKey)) {
            String countSql = "select count(*) from slogintbl where tradeno =? ";
            List<String> countParams = new ArrayList<>();
            countParams.add(redisKey);
            try {
                int count = daoutil.queryCountSql(countSql, countParams);
                if (0 != count) {
                    List<String> params = new ArrayList<>();
                    SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd HH:mm:ss");
                    
                    params.add(sf.format(new Date()));
                    params.add(redisKey);
                    String sql = "update slogintbl set logoutdate=? where tradeno=?";
                    daoutil.updateOrSaveSql(sql, params);
                    transactionManager.commit(status);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                logger.debug(Exceptions.getStackTraceAsString(e));
                transactionManager.rollback(status);
            }
        }
    }
}
  • 方式二
package com.aaa.bbb.listen;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.transaction.Transactional;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.aaa.bbb.common.Exceptions;
import com.aaa.bbb.common.SpringContextHolder;
import com.aaa.bbb.dao.util.Daoutil;


public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    private static final Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListener.class);
    @Autowired
    private Daoutil daoutil;

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
    /**
     *
     * 監(jiān)聽redis過期失效的key
     */
    @Override
    public void onMessage(Message message, byte[] pattern){
        //手動開啟hibernate的事務(wù)
        HibernateTransactionManager transactionManager = SpringContextHolder.getBean("txManager");
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔離級別,開啟新事務(wù),這樣會比較安全些。
        TransactionStatus status = transactionManager.getTransaction(def); // 獲得事務(wù)狀態(tài)
        String redisKey = message.toString();
        logger.info("即將要失效的Key:" + redisKey);
        //System.out.println("即將要失效的Key:" + redisKey);
        if (StringUtils.isNotBlank(redisKey)) {
            String countSql = "select count(*) from slogintbl where tradeno =? ";
            List<String> countParams = new ArrayList<>();
            countParams.add(redisKey);
            try {
                int count = daoutil.queryCountSql(countSql, countParams);
                if (0 == count) {
                    return;//使用return
                } else {
                    List<String> params = new ArrayList<>();
                    SimpleDateFormat sf=new SimpleDateFormat("yyyyMMdd HH:mm:ss");
                    
                    params.add(sf.format(new Date()));
                    params.add(redisKey);
                    String sql = "update slogintbl set logoutdate=? where tradeno=?";
                    daoutil.updateOrSaveSql(sql, params);
                    transactionManager.commit(status);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                logger.debug(Exceptions.getStackTraceAsString(e));
                transactionManager.rollback(status);
            }finally {
                try {
                transactionManager.getSessionFactory().getCurrentSession().close();
                }catch(Exception e){
                    logger.debug("關(guān)閉資源異常");
                }
            }

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

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