`
huiseyiyu
  • 浏览: 102488 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

数据库能力放通(记录)

 
阅读更多

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

   实现思路:本想用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);
    }
    
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    access数据库一日通讲义

    郭定安老师的“Access数据库一日通讲义”提供了深入浅出的教程,帮助学习者快速掌握数据库的基本概念和操作。 在数据库设计中,正规化(Normalization)是一个至关重要的概念。正规化是为了避免数据冗余和提高数据...

    用友通总账数据库培训课件

    【用友通总账数据库培训课件】是一个专注于讲解如何管理和操作用友通财务软件中的总账数据库的教育材料。这个课程旨在帮助学员深入理解总账数据库的基本概念、功能以及在实际业务操作中的应用。以下是根据标题和描述...

    使用异步方式查询数据库记录

    这种方式允许其他任务在等待数据库响应的同时继续执行,避免了阻塞主线程,提高了程序的并发能力。本文将深入探讨如何在不同编程语言和框架中实现异步数据库查询,并提供实践示例。 1. **JavaScript(Node.js + ...

    QQ企业通 socket 包含数据库和程序使用说明

    数据库方面,QQ企业通可能使用了关系型数据库(如MySQL、SQL Server)或者非关系型数据库(如MongoDB),用于存储用户账户信息、好友列表、聊天记录等。这些数据通常会按照一定的模式设计,如用户表、好友关系表、...

    KEPServerEX数据写入数据库案例.pdf

    KEPServerEX是一款由Kepware公司开发的OPC服务器软件,它允许用户从各种工业设备和控制系统中收集数据,并将其整合到一个统一的接口...对于需要实时监控和历史数据记录的工业环境,KEPServerEX的这种能力显得尤为重要。

    oracle数据库入门书

    Oracle数据库概念与SQLServer等其他关系型数据库有许多共通之处,例如,数据库、表、记录、以及表的增删改查操作都是基本概念。然而,Oracle作为一个基于对象的关系型数据库,其在数据存储和管理上也体现了一些面向...

    中安威士数据库防火墙系统(VS-FW).docx

    6. 安全审计:记录数据库访问的详细信息,包括用户、IP、请求数据库等,便于审计和分析。 7. 报表功能:提供多种审计报表和安全趋势分析,帮助企业满足合规要求,加速审计过程。 8. 技术优势:拥有全自主技术,...

    ustb-计通必修-数据库原理实验报告

    这份“ustb-计通必修-数据库原理实验报告”显然涵盖了北京科技大学(USTB)计算机科学与技术专业数据库课程的多个实验,总计超过30个。通过这些实验,学生能够深入理解数据库的工作机制,并掌握SQL语言、关系模型、...

    数据库应用与原理期末复习资料

    10. **试卷结构与题型**:考试可能包含填空、判断、选择和设计题,测试学生对基本概念的理解以及在实际问题中的应用能力。 复习时,应重点理解和掌握这些知识点,并通过练习题来巩固,尤其是SQL语句的编写、关系...

    中安威士数据库防火墙系统(VS-FW)参考.pdf

    3. 攻击检测和保护:实时检测用户对数据库进行的 SQL 注入和缓冲区溢出攻击,并报警或者阻止攻击行为,同时详细记录攻击操作发生的时间、来源 IP、用户名、攻击代码等信息。 4. 自动建立访问模型:系统将自动学习每...

    校园一卡通通过客户端操作数据库完整实例

    【标题】"校园一卡通通过客户端操作数据库完整实例"揭示了如何使用Java客户端与数据库进行交互,实现校园一卡通系统的功能。在这个系统中,一卡通不仅用于支付餐饮、购物等消费,也可能涉及到门禁、图书借阅等多种...

    企业及时通,java 编写的,oracle 数据库设计

    在“企业及时通”中,可能包含了用户信息表、消息表、会话记录等多种表,构成了一套完整的数据库架构。 2. **关系模型**:Oracle支持标准的关系型数据库模型,通过建立实体间的一对一、一对多、多对多等关系,实现...

    Dreamweaver开发的程序与数据库的连接

    标题 "Dreamweaver开发的程序与数据库的连接" 涉及到的是使用Adobe Dreamweaver这款强大的网页设计和开发工具来创建与数据库交互的应用程序。Dreamweaver提供了直观的界面和集成的开发环境,使得开发者能够轻松地...

    Delphi数据库开发第2章数据库开发概述.pdf

    数据库中的关键字段是区分数据表格中记录的独特标识,确保数据的唯一性。在Paradox和dBase等类型的数据库中,数据表格通常有一个关键字段。 【数据的存取】 Delphi通过数据访问组件(Data Access Components)实现...

    【实验报告】 数据库的定义与单表查询

    【实验报告】 数据库的定义与单表查询 实验的目的在于让学习者深入理解数据库的基本...通过这个实验,学生不仅可以掌握数据库的基本操作,还能锻炼分析和设计数据库的能力,从而更好地应用于实际的图书管理系统中。

    数据挖掘与数据库开发

    硬件需要能够处理大数据量的存储和计算能力,可能包括高性能的服务器和足够的存储空间。系统开发平台则可能包括数据库管理系统(如Oracle、MySQL等)、数据挖掘工具(如R、Python的Pandas和Scikit-learn库)以及可视...

    数据库查询语言----SQL21天自学通

    10. 分区和分区函数:在大型数据库中,通过分区可以将数据分布在多个物理存储上,以提高查询效率和管理能力。 在自学过程中,建议通过实际操作来加深理解,可以创建自己的数据库并进行练习。同时,理解SQL语句的...

    八通道无纸记录仪通讯软件

    3. **数据记录与存储**:软件可以定期或连续地从记录仪获取数据,并保存在本地硬盘,形成历史数据库,方便后期数据分析。 4. **数据导出与报告**:用户可以将收集到的数据导出为常见的格式,如CSV、Excel,便于...

    OBD平台数据库设计说明1

    以下是根据提供的修改记录总结的数据库设计知识点: 1. **车辆状态**:车辆状态增加了防盗类型,这表明平台需要记录车辆的防盗状态,可能包括车辆是否被非法开启或移动等信息。 2. **GPS和WiFi状态**:库存设备表...

Global site tag (gtag.js) - Google Analytics