前言
LZ最近失业,梳理下最近一个项目的 项目结构-供应链系统
接着上一篇博客 http://www.cnblogs.com/buruainiaaaa/p/6786527.html
上篇说到整套系统分为3套子系统,这篇 说下缓存结构
Sqlite 简介:
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。(比较官方)
其官网地址 https://www.sqlite.org/
LZ打算说下自己眼中的Sqlite:
1.自给自足:sqlite能够包含自己的表,试图,索引,事物 等等
2.无服务器:纯文件形式,不需要跟sqlserver一样 启动系统服务。
3.零配置:文件不需要任何配置,只需要配置db文件的路径即可,使用方便
4.事物性:sqlite 支持参数化,事物回滚
5.轻量级,跨平台
但是 sqlite 也不是没有缺点,LZ个人认为,最大的不足就是:并发写
sqlite 比较使用于做CS端的缓存,一整套业务系统 难免会有多个子系统,在进行sqlite 操作的时候,肯定会出现并发写的情况,这种情况下就需要对写 进行控制
进程互斥锁Mutex
这里 我就不介绍Mutex 是什么,总之 Mutex 能解决 sqlite 在多进程 多线程情况下的 互斥问题
private Mutex writerLock = new Mutex(false, "Global\JiupiSqlLite");
等待
writerLock.WaitOne(30000)
释放
writerLock.ReleaseMutex();
使用互斥锁,保证写操作的互斥性
public class SqliteConnMutex : IDisposable { /// <summary> /// 互斥锁 /// </summary> private Mutex writerLock = new Mutex(false, "Global\MySqlLite"); /// <summary> /// 互斥锁保护对象 /// </summary> private SQLiteConnection connection = null; /// <summary> /// 获取写操作连接 /// </summary> /// <returns></returns> public SQLiteConnection GetConnection() { try { while (true) { if (writerLock.WaitOne(30000)) { if (connection.State == System.Data.ConnectionState.Closed) { connection = new SQLiteConnection(SQLiteHelper.connectionString); } return connection; } Thread.Sleep(1000); } } catch (Exception ex) { throw ex; } } //供程序员显式调用的Dispose方法 public void Dispose() { Dispose(true); } //protected的Dispose方法,保证不会被外部调用。 protected void Dispose(bool disposing) { if (disposing) { try { writerLock.ReleaseMutex(); } catch (Exception ex) { } } } }
SQLiteHelper对sqlite 写操作的调用
/// <summary> /// 进程锁 /// </summary> /// <param name="SQLString"></param> /// <returns></returns> public static int ExecuteMutexSql(string SQLString, SQLiteParameter[] param = null) { SQLiteConnection connection = null; try { using (SqliteConnMutex mutex = new SqliteConnMutex()) { connection = mutex.GetConnection(); if (connection == null) { throw new Exception("connection对象错误"); } if (connection == null) { throw new Exception("connection不能为空"); } using (SQLiteCommand cmd = new SQLiteCommand()) { try { if (connection.State != ConnectionState.Open) { connection.Open(); } PrepareCommand(cmd, connection, null, SQLString, param); //Thread.Sleep(100); int rows = cmd.ExecuteNonQuery(); return rows; } catch (System.Data.SQLite.SQLiteException E) { if (connection != null && connection.State != ConnectionState.Closed) { connection.Clone(); } throw new Exception(E.Message); } } } } catch (Exception ex) { throw ex; } }
sqlite 读操作的 方法封装
/// <summary> /// 执行查询语句,返回DataSet /// </summary> /// <param name="SQLString">查询语句</param> /// <returns>DataSet</returns> public static DataSet Query(string SQLString) { using (SQLiteConnection connection = new SQLiteConnection(connectionString)) { DataSet ds = new DataSet(); try { connection.Open(); SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection); command.Fill(ds, "ds"); } catch (System.Data.SQLite.SQLiteException ex) { throw new Exception(ex.Message); } return ds; } }
经过测试,在 多线程,多进程情况下,可以往同一个db里边新增数据
结语:
附带