数据库操作是异步的,在高并发的情况下有可能出现以下的情形:
1、线程A对数据库的表table_1进行插入操作,同时另一线程B同样对表table_2进行查询最新数据操作。这个时候线程B理想的获取值应该是线程A插入的数据,但实际上却不一定取得理想值。
2、频繁操作数据库不仅会造成数据不能及时更新,同时还会大量消耗机器的性能。
一般不涉及并发操作的可进行下面的数据库操作
1.1:Service主操作:包含dao对数据库的增查操作
1.2:Service业务操作1:查找并进行逻辑运算
1.3:Service业务操作2:插入数据
下面介绍一种简单有效的解决方案(轻量级):使用public static对插入数据进行缓存:
基础Service:
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@Service("dataBasesConcurrencyServ")
public class DataBasesConcurrencyServImpl implements DataBasesConcurrencyServ{
@Autowired
private DouniuDao douniuDao;
private static Douniu douniuCache = null;
private String douniuCacheLockStr = "douniuCacheLockStr";
//其它类只能够调用该方法保存douniu,以及setDouniuCache,以保证数据库的线程安全
public Douniu setDouniu(Douniu douniu) {
// 代码块加锁保障线程安全
synchronized (douniuCacheLockStr.intern()) {
douniuDao.save(douniu);
setDouniuCache(douniu);
return douniu;
}
}
private void setDouniuCache(Douniu douniu) {
if (douniu == null)
return;
douniuCache = new Douniu();
BeanUtils.copyProperties(douniu, douniuCache);
}
public Douniu getDouniuCache() {
synchronized (douniuCacheLockStr.intern()) {
if (douniuCache == null) {
// 启动服务器时,第一条缓存应该从数据库拿
douniuCache = douniuDao.loadNew(1);
}
return douniuCache;
}
}
}
Control层操作:
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.sun.net.httpserver.Authenticator.Success;
@RequestMapping("/dataBasesConcurrencyCon")
@Controller
public class DataBasesConcurrencyCon {
@Autowired
private DataBasesConcurrencyServ dataBasesConcurrencyServ;
/**
* 获取douniu实时数据(并保证数据库的线程安全)
* @return
*/
@RequestMapping("/getDouniuNow")
@ResponseBody
public Object getDouniuNow(){
try{
Map<String,Object> successMap = new HashMap<String, Object>();
successMap.put("sccessMap", true);
successMap.put("douniu",dataBasesConcurrencyServ.getDouniuCache());
return successMap;
}catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping("/saveDouniu")
@ResponseBody
public Object saveDouniu(Douniu save){
try{
dataBasesConcurrencyServ.setDouniu();
Map<String,Object> successMap = new HashMap<String, Object>();
successMap.put("sccessMap", true);
return successMap;
}catch (Exception e) {
e.printStackTrace();
}
}
}
以上就是通过静态成员变量来进行缓存操作的简单有效方法。