mysql 并发避免锁表_MYSQL锁表的用法,防止并发情况下的重复数据
項目中有些使用的redis存儲,當對redis進行rehash的時候感覺是比較麻煩的。于是寫了個簡單的讀取redis到數據庫的關鍵方法。僅供參考。
package com.redis.web;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import redis.clients.jedis.Jedis;
import com.redis.entity.RedisTable;
public class RedisPersistence {
/**
* 存儲所有的redis對象方法
*/
public static void saveAllRedis(final String redisIp,final int redisPort,final String appCode) {
Jedis redis = new Jedis(redisIp, redisPort);// 連接redis
// redis.auth("redis");//驗證密碼
// KEY操作
Set keys = redis.keys("*");// 列出所有的key,查找特定的key如:redis.keys("foo")
Iterator t1 = keys.iterator();
while (t1.hasNext()) {
Object obj1 = t1.next();
saveRedisObject(redis, obj1 + "", redisIp, redisPort + "", appCode);
}
}
/**
* 存儲單個對象
* @param redis
* @param redisKey
* @param macIp
* @param port
* @param appCode
*/
private static void saveRedisObject(final Jedis redis,final String redisKey,final String macIp,final String port,final String appCode) {
String redisType = redis.type(redisKey);
RedisTable redisTable = new RedisTable();
redisTable.setAppCode(appCode);
redisTable.setCreateTime(new Date());
redisTable.setMacIp(macIp);
redisTable.setPort(port);
redisTable.setRedisKey(redisKey);
redisTable.setRedisType(redisType);
redisTable.setRemark("");
redisTable.setUpdateTime(new Date());
//set集合
if("set".equalsIgnoreCase(redisType)){
Set setStrings = redis.smembers(redisKey);//獲取key的所有set集合
if(null != setStrings && !setStrings.isEmpty()){
Iterator setIterator = setStrings.iterator() ;
while(setIterator.hasNext()){
Object obj1 = setIterator.next();
redisTable.setRedisValue(obj1+"");
printRedis(redisTable);//保存每一個set記錄
}
}
//hash集合
}else if("hash".equalsIgnoreCase(redisType)){
Set hashSets = redis.hkeys(redisKey);
if(null != hashSets && !hashSets.isEmpty()){
Iterator setIterator = hashSets.iterator() ;
while(setIterator.hasNext()){
String objectName = setIterator.next()+"";
redisTable.setObjectName(objectName);
redisTable.setRedisValue(redis.hget(redisKey, objectName));
printRedis(redisTable);//保存每一個set記錄
}
}
//list集合
}else if("list".equalsIgnoreCase(redisType)){
Long listLen = redis.llen(redisKey);
for (Long i = 0L; i < listLen; i++) {
redisTable.setRedisValue(redis.lindex(redisKey, i));
printRedis(redisTable);
}
//sortedset集合
}else if("sortedset".equalsIgnoreCase(redisType)){
//Long redisLenth = redis.zcard(redisKey);
Set sortedsets = redis.zrange(redisKey, 0, -1);
if(null != sortedsets && !sortedsets.isEmpty()){
Iterator setIterator = sortedsets.iterator() ;
while(setIterator.hasNext()){
String sortedMember = setIterator.next() +"";
redisTable.setRedisValue(sortedMember);
redisTable.setScore("" +redis.zscore(redisKey, sortedMember));
printRedis(redisTable);//保存每一個sortedset記錄
}
}
//string集合
}else if("string".equalsIgnoreCase(redisType)){
redisTable.setRedisValue(redis.get(redisKey));
printRedis(redisTable);//保存記錄
}else{
System.out.println("UnknowRedisType-----redisType: " +redisType+" objValue: "+redis.get(redisKey));
}
}
//打印輸出
public static void printRedis (RedisTable redisTable) {
System.out.println("redisType:"+redisTable.getRedisType()
+ " redisKey:"+redisTable.getRedisKey()
+ " ObjectName:"+redisTable.getObjectName()
+ " redisValue:"+redisTable.getRedisValue()
+ " redisScore:"+redisTable.getScore()
);
}
public static void main(String[] args) {
String redisIp = "127.0.0.1";//redis的IP地址
int redisPort = 6379;//redis的端口號
String appCode = "FUYOU";//根據不同的應用區分的appcode
saveAllRedis(redisIp,redisPort,appCode);
}
}
其中的appCode是不需要的,這里只是為了針對于不同的應用,可以使用同一個redis進行持久化備份而已(通過appcode來區分)。
其中使用的RedisTable實例如下:
package com.redis.entity;
import java.util.Date;
public class RedisTable {
private Long redisId; //保存redis的主鍵ID
private String redisType;//redis的類型如:set/list/hash/sortedset/string
private String redisKey;//保存redis時使用的key
private String objectName;//此屬性主要用于hash數據結構時,保存member的
private String redisValue;//存儲的redis的值
private String keyToken;//保存Token時,為區分拼接的字符串
private String score;//此屬性為sortedset數據結構時,保存的score值
private Date createTime;//創建時間
private Date updateTime;//更新時間
private String macIp;//redis的IP地址 當然此處也可以存儲mac地址
private String port;//redis使用的端口號
private String appCode;//應用區分碼
private String remark;//備注
private String isModify;//是否修改。此屬性可以用于增量備份時,即在每個redis存儲時可以更具key多存儲一個屬性isModify。 如果有修改,則置為 Y,否則為N.
///此處省略 setter and getter 方法
}
以上方法可以擴充用于redis備份中心。
在使用redis增量備份時,請根據rediskey在數據塊中查找是否存在。根據更新值返回的0或者是1,進行更新或者新增的操作。
當然數據庫的表結構目前只是一張表,如果數據量很大的情況下,可以將端口、IP、appCode信息存儲到單獨的一張表,減少數據冗余。
以上的時間復雜度以及效率上并沒有優化。如果要求比較高,請自行優化。
希望各位大俠給出建議,共同進步!
原文:http://blog.csdn.net/dreamzml/article/details/19119605
總結
以上是生活随笔為你收集整理的mysql 并发避免锁表_MYSQL锁表的用法,防止并发情况下的重复数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql的dockerfile_Doc
- 下一篇: mysql分布式数据库实践论文_新浪微博