数据库能力放通(记录)

   要求数据库中断的情况下,部分功能能力放通:

   实现思路:本想用csv文件存储临时数据,发现用数组拼装太麻烦,后直接采用对象序列化存储

   采用读写所操作数据,在业务操作时,捕捉数据库中断异常,把对象写入缓存文件中,

   数据库正常后,任意一个用户登陆,开辟一个线程进行读操作,写入数据库,然后删除缓存文件

 

   过程中发现学序列化追加存储,无法正常读取,最后一个工具类是处理该问题的

/**
 * 
 * 缓存文件读取
 * <读取缓存文件,对缓存数据进行数据库持久化操作>
 * 
 * @author  xxx
 * @version  [V01, 2011-9-6]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Scope("prototype")
@Component
public class ReadTask extends Thread
{
    private Log log = LogFactory.getLog(ReadTask.class);
    
    /**
     * 文件读写操作类
     */
    @Autowired
    private ReadWriteLockLogic readWriteLockOperator;
    
    @Autowired()
    private EventRepository eventRepository;
    
    /**
     * 执行读取任务
     */
    public synchronized void run()
    {
        
        if (this.readWriteLockOperator != null)
        {
            
            //1、读取文件拼装对象            
            List<EventBean> eventBeanList = null;
            
            try
            {
                eventBeanList = readWriteLockOperator.read();
            }
            catch (Exception e)
            {
                log.error(e.getStackTrace());
            }
            
            //4、删除文件
            readWriteLockOperator.delete();
            
            if (null == eventBeanList || eventBeanList.isEmpty())
            {
                return;
            }
            
            //3、成功保存到数据库(如果出现异常,如果普通异常记录失败行数,如果是数据库中断,回滚)                    
            List<EventBean> faiList = eventRepository.insertEventLink(eventBeanList);
            
            if (null == faiList || faiList.isEmpty())
            {
                return;
            }
            
            //5、对于数据库突然中断的数据,覆写回缓存文件            
            try
            {
                readWriteLockOperator.write(faiList, false);
            }
            catch (Exception e)
            {
                log.error(e.getStackTrace());
            }
        }
    }
    
}
/**
 * 文件读写操作类
 * <针对文件的续写加入读写锁,避免冲突>
 * 
 * @author  xxx
 * @version  [V1.0, 2011-9-6]
 * @see  [相关类/方法]
 * @since  [ECC/C02]
 */
@Component
public class ReadWriteLockLogic
{
    
    /**
     * 文件路径
     */
    private String path;
    
    /**
     * 初始化一个 ReadWriteLock
     */
    private ReadWriteLock lock = new ReentrantReadWriteLock();
    
    private Log log = LogFactory.getLog(ReadWriteLockLogic.class);
    
    /**
     * 读数据缓存文件
     * 
     * @return EventBean
     */
    public List<EventBean> read()
    //        throws Exception
    {
        
        // 得到 readLock 并锁定
        Lock readLock = lock.readLock();
        readLock.lock();
        
        List<EventBean> eventBeanList = new ArrayList<EventBean>();
        
        ObjectInputStream ois = null;
        
        FileInputStream fis = null;
        
        File file = new File(path);
        
        //赋予创建文件权限
        //        file.setWritable(true, false);
        
        if (!file.exists())
        {
            return null;
        }
        try
        {
            fis = new FileInputStream(file);
            
            ois = new ObjectInputStream(fis);
            
            Object obj;
            
            while (fis.available() > 0)
            {
                obj = ois.readObject();
                if (obj instanceof EventBean)
                {
                    EventBean eventBean = (EventBean)obj;
                    eventBeanList.add(eventBean);
                }
            }
        }
        catch (Exception e)
        {
            log.error(e.getStackTrace());
        }
        finally
        {
            if (null != fis)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e)
                {
                    log.error(e.getStackTrace());
                }
            }
            
            if (null != ois)
            {
                try
                {
                    ois.close();
                }
                catch (IOException e)
                {
                    log.error(e.getStackTrace());
                }
            }
            
            readLock.unlock();//一定要保证锁的释放
        }
        
        return eventBeanList;
    }
    
    /**
     * 写文件
     * 
     * @param eventBeanList 事件对象
     * @param isVerride 是否覆盖
     * @return boolean 是否正确写入
     */
    public boolean write(List<EventBean> eventBeanList, boolean isVerride)
    //        throws Exception
    {
        // 得到 writeLock 并锁定
        Lock writeLock = lock.writeLock();
        writeLock.lock();
        
        //带有true参数的FileOutputStream
        EccObjectOutputStream outSteam = null;
        
        FileOutputStream fos = null;
        
        try
        {
            
            File file = new File(path);
            
            //赋予创建文件权限
            //            file.setWritable(true, false);
            
            if (!file.getParentFile().exists())
            {
                try
                {
                    if (!file.getParentFile().mkdirs())
                    {
                        return false;
                    }
                }
                catch (Exception e)
                {
                    log.error(e.getStackTrace());
                    return false;
                }
            }
            if (!file.exists() && null != eventBeanList)
            {
                try
                {
                    if (!file.createNewFile())
                    {
                        return false;
                    }
                }
                catch (Exception e)
                {
                    log.error(e.getStackTrace());
                    return false;
                }
            }
            
            fos = new FileOutputStream(file, isVerride);
            outSteam = EccObjectOutputStream.newInstance(file, fos);
            
            if (null != eventBeanList)
            {
                for (EventBean eventBean : eventBeanList)
                {
                    outSteam.writeObject(eventBean);
                }
            }
            outSteam.flush();
        }
        catch (Exception e)
        {
            log.error(e.getStackTrace());
            return false;
        }
        finally
        {
            
            if (null != fos)
            {
                try
                {
                    fos.close();
                }
                catch (IOException e)
                {
                    log.error(e.getStackTrace());
                }
            }
            
            if (null != outSteam)
            {
                try
                {
                    outSteam.close();
                }
                catch (IOException e)
                {
                    log.error(e.getStackTrace());
                }
            }
            
            writeLock.unlock();//一定要保证锁的释放
        }
        
        return true;
    }
    
    /**
     * 删除文件
     * 如果文件存在则删除文件
     * 
     * @return Boolean
     */
    public Boolean delete()
    {
        File file = new File(path);
        if (file.exists())
        {
            try
            {
                return file.delete();
            }
            catch (Exception e)
            {
                log.error("delete dbcache file faild");
                log.error(e.getStackTrace());
            }
            
        }
        return false;
    }
    
    /**
     * 判断文件是否存在
     * 
     * @return Boolean
     */
    public Boolean isExist()
    {
        
        File file = new File(path);
        
        return file.exists();
        
    }
    
    public String getPath()
    {
        return path;
    }
    
    public void setPath(String path)
    {
        this.path = path;
    }
    
}
/**
 * 缓存文件写入
 * 事件bean加密转换为数组写入缓存文件中
 * 
 * @author  xxx
 * @version  [版本号, 2011-9-7]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Component
public class WriteTask
{
    
    @Autowired
    private ReadWriteLockLogic readWriteLockOperator;
    
    /**
     * 缓存文件写方法
     * 
     * @param eventBeanList 事件对象集合
     * @return RestResponse
     */
    public RestResponse write(List<EventBean> eventBeanList)
//        throws Exception
    {
        RestResponse response = new RestResponse();
        
        //同步读写锁数据按格式写入文件(加密)         
        if (readWriteLockOperator.write(eventBeanList, true))
        {
            response.setSuccess(true);
            response.setRetCode(ReturnCode.SUCCESS);
        }
        else
        {
            response.setRetCode(ReturnCode.FAILURE);
            response.setSuccess(false);
        }
        
        return response;
    }
    
}
/**
 * 
 * 针对输出流的封装类
 * 解决序列化对象追加写入文件无法读取问题
 * @author  xxx
 * @version  [版本号, 2011-9-9]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class EccObjectOutputStream extends ObjectOutputStream
{
    /**
     * 公共文件
     */
    private static File f;
    
    /**  
     * 初始化静态文件对象,并返回类对象  
     * @param file 文件对象,用于初始化静态文件对象  
     * @param out 输出流  
     * @return MyObjectOutputStream  
     * @throws IOException  
     */
    public static EccObjectOutputStream newInstance(File file, OutputStream out)
        throws IOException
    {
        f = file;//本方法最重要的地方:构建文件对象,是两个文件对象属于同一个   
        //return new EccObjectOutputStream(out, f);
        return new EccObjectOutputStream(out);//修改pmd问题
    } 
    
    /**
     * {@inheritDoc}
     */
    @Override
    protected void writeStreamHeader()
        throws IOException
    {
        if (!f.exists() || (f.exists() && f.length() == 0))
        {
            super.writeStreamHeader();
        }
        else
        {
            super.reset();
        }
    }
    
    /**
     * <默认构造函数>
     */
    //public EccObjectOutputStream(OutputStream out, File f) //修改pmd问题
    public EccObjectOutputStream(OutputStream out)
        throws IOException
    {
        super(out);
    }
    
}

猜你喜欢

转载自huiseyiyu.iteye.com/blog/1180341
今日推荐