问题代码(监听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);
}
/**
*
* 监听redis过期失效的key
*/
@Override
public void onMessage(Message message, byte[] pattern){
//手动开启hibernate的事务
HibernateTransactionManager transactionManager = SpringContextHolder.getBean("txManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
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);
}
}
}
}
结果
没有关闭资源导致连接池耗尽
解决方式
- 方式一
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);
}
/**
*
* 监听redis过期失效的key
*/
@Override
public void onMessage(Message message, byte[] pattern){
//手动开启hibernate的事务
HibernateTransactionManager transactionManager = SpringContextHolder.getBean("txManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
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);
}
/**
*
* 监听redis过期失效的key
*/
@Override
public void onMessage(Message message, byte[] pattern){
//手动开启hibernate的事务
HibernateTransactionManager transactionManager = SpringContextHolder.getBean("txManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
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("关闭资源异常");
}
}
}
}
}
网友评论