zoukankan      html  css  js  c++  java
  • SQLite数据库在多线程写锁文件的解决办法

    参考了很多SQLITE数据库多线程的解决办法 我自己写了一个SQLITEHELPER 来解决这个问题

    希望大家多多指教

    调用的时候

     SQLLiteDBHelper _SQLLiteDBHelper = new SQLLiteDBHelper();

     _SQLLiteDBHelper.Dispose();

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    using System.Data.SQLite;
    using System.Threading;
    
    namespace DAL
    {
        public class SQLLiteDBHelper : IDisposable
        {
            public static string Connectionstring = "";
            /// <summary>
            /// 获得连接对象
            /// </summary>
            /// <returns></returns>
            public  SQLiteConnection GetSQLiteConnection()
            {
                //return new SQLiteConnection(Connectionstring);
                SQLiteConnection conn = new SQLiteConnection();
                try
                {
      
                    conn.ConnectionString = Connectionstring;
                    if (conn.State.Equals(ConnectionState.Closed))
                    {
                        conn.DefaultTimeout = 5000;
                        conn.Open();
                      
                    }
             
                }
                catch (Exception ee)
                {
    
                    //OAFile.ErrorLog(OAFile.GetCurrUrl(), "链接字符串错误,请检查,详细错误:" + ee.Message);
                }
                return conn;
            }
    
            /// <summary>
            /// COMMAND初始化
            /// </summary>
            /// <param name="cmd"></param>
            /// <param name="conn"></param>
            /// <param name="cmdText"></param>
            /// <param name="p"></param>
            private  void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, string cmdText, params object[] p)
            {
                try
                {
                    if (conn.State != ConnectionState.Open)
                        conn.Open();
                    cmd.Parameters.Clear();
                    cmd.Connection = conn;
                    cmd.CommandText = cmdText;
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandTimeout = 30;
                    if (p != null)
                    {
                        foreach (object parm in p)
                            cmd.Parameters.Add(parm);
                    }
                }
                catch (Exception)
                {
                    
    
                }
    
            }
    
            /// <summary>
            /// 批量执行带参数的SQL语句 事务 并返回执行结果
            /// </summary>
            /// <param name="SQLStringList"></param>
            /// <param name="PramsList"></param>
            /// <returns></returns>
            public  string ExecuteSqlTran(List<string> SQLStringList, List<SQLiteParameter[]> PramsList)
            {
                AcquireWriteLock();
                string result = "执行成功";
                using (SQLiteConnection conn = GetSQLiteConnection())
                {
                    using (SQLiteCommand cmd = new SQLiteCommand())
                    {
                        try
                        {
                            cmd.Connection = conn;
                            SQLiteTransaction tx = conn.BeginTransaction();
                            cmd.Transaction = tx;
                            try
                            {
                                for (int i = 0; i < SQLStringList.Count; i++)
                                {
                                    if (SQLStringList[i].Trim().Length > 1)
                                    {
                                        PrepareCommand(cmd, conn, SQLStringList[i].Trim(), PramsList[i]);
                                        cmd.ExecuteNonQuery();
                                        cmd.Parameters.Clear();
                                    }
                                }
                                tx.Commit();
                            }
                            catch (Exception ex)
                            {
                                tx.Rollback();
                                result = ex.Message.Trim();
                            }
                        }
                        catch (Exception)
                        {
    
                            result = "lock";
                        }
                      
                    }
                }
                return result;
            }
    
            /// <summary>
            /// 批量执行带参数的SQL语句 事务 并返回执行结果
            /// </summary>
            /// <param name="SQLStringList"></param>
            /// <param name="PramsList"></param>
            /// <returns></returns>
            public  string ExecuteSqlTran(List<string> SQLStringList)
            {
                AcquireWriteLock();
                string result = "执行成功";
                using (SQLiteConnection conn = GetSQLiteConnection())
                {
                    using (SQLiteCommand cmd = new SQLiteCommand())
                    {
                        cmd.Connection = conn;
                        SQLiteTransaction tx = conn.BeginTransaction();
                        cmd.Transaction = tx;
                        try
                        {
                            for (int i = 0; i < SQLStringList.Count; i++)
                            {
                                if (SQLStringList[i].Trim().Length > 1)
                                {
                                    PrepareCommandNoParameters(cmd, conn, SQLStringList[i].Trim());
                                    cmd.ExecuteNonQuery();
                                   // cmd.Parameters.Clear();
                                }
                            }
                            tx.Commit();
                        }
                        catch (Exception ex)
                        {
                            if (conn.State!=ConnectionState.Closed)
                            {
                                tx.Rollback();
                            }
    
                            result = ex.Message.Trim();
                        }
                    }
                }
                return result;
            }
    
            /// <summary>
            /// COMMAND初始化
            /// </summary>
            /// <param name="cmd"></param>
            /// <param name="conn"></param>
            /// <param name="cmdText"></param>
            /// <param name="p"></param>
            private  void PrepareCommandNoParameters(SQLiteCommand cmd, SQLiteConnection conn, string cmdText)
            {
                try
                {
                    if (conn.State != ConnectionState.Open)
                        conn.Open();
                    cmd.Connection = conn;
                    cmd.CommandText = cmdText;
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandTimeout = 30;
                }
                catch (Exception)
                {
    
                }
            }
    
            /// <summary>
            /// 返回DataSet
            /// </summary>
            /// <param name="cmdText"></param>
            /// <param name="p"></param>
            /// <returns></returns>
            public  DataSet DS(string cmdText, params object[] p)
            {
                DataSet ds = new DataSet();
                SQLiteCommand command = new SQLiteCommand();
                using (SQLiteConnection connection = GetSQLiteConnection())
                {
                    PrepareCommand(command, connection, cmdText, p);
                    SQLiteDataAdapter da = new SQLiteDataAdapter(command);
                    da.Fill(ds);
                }
                return ds;
            }
    
            /// <summary>
            /// 返回DataTable
            /// </summary>
            /// <param name="cmdText"></param>
            /// <param name="p"></param>
            /// <returns></returns>
            public  DataTable DT(string cmdText, params object[] p)
            {
                DataSet ds = new DataSet();
                SQLiteCommand command = new SQLiteCommand();
                using (SQLiteConnection connection = GetSQLiteConnection())
                {
                    PrepareCommand(command, connection, cmdText, p);
                    SQLiteDataAdapter da = new SQLiteDataAdapter(command);
                    da.Fill(ds);
                }
                return ds.Tables[0];
            }
    
            /// <summary>
            /// 返回DataTable
            /// </summary>
            /// <param name="cmdText"></param>
            /// <param name="p"></param>
            /// <returns></returns>
            public  DataTable DT(string cmdText)
            {
                DataSet ds = new DataSet();
                SQLiteCommand command = new SQLiteCommand();
                using (SQLiteConnection connection = GetSQLiteConnection())
                {
                    PrepareCommandNoParameters(command, connection, cmdText);
                    SQLiteDataAdapter da = new SQLiteDataAdapter(command);
                    da.Fill(ds);
                }
                return ds.Tables[0];
            }
    
            /// <summary>
            /// 返回执行数据的行数
            /// </summary>
            /// <param name="cmdText"></param>
            /// <param name="p"></param>
            /// <returns></returns>
            public  DataRow ExecuteDataRow(string cmdText, params object[] p)
            {
                DataSet ds = DS(cmdText, p);
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                    return ds.Tables[0].Rows[0];
                return null;
            }
    
    /// <summary> /// 返回受影响的行数 /// </summary> /// <param name="cmdText">a</param> /// <param name="commandParameters">传入的参数</param> /// <returns></returns> public int ExecuteNonQuery(string cmdText, params object[] p) { AcquireWriteLock(); SQLiteCommand command = new SQLiteCommand(); using (SQLiteConnection connection = GetSQLiteConnection()) { PrepareCommand(command, connection, cmdText, p); return command.ExecuteNonQuery(); } } /// <summary> /// 返回受影响的行数 /// </summary> /// <param name="cmdText">a</param> /// <param name="commandParameters">传入的参数</param> /// <returns></returns> public int ExecuteNonQuery(string cmdText) { AcquireWriteLock(); SQLiteCommand command = new SQLiteCommand(); using (SQLiteConnection connection = GetSQLiteConnection()) { PrepareCommandNoParameters(command, connection, cmdText); return command.ExecuteNonQuery(); } } /// <summary> /// 返回SqlDataReader对象 /// </summary> /// <param name="cmdText"></param> /// <param name="commandParameters">传入的参数</param> /// <returns></returns> public SQLiteDataReader ExecuteReader(string cmdText, params object[] p) { SQLiteCommand command = new SQLiteCommand(); SQLiteConnection connection = GetSQLiteConnection(); try { PrepareCommand(command, connection, cmdText, p); SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection); return reader; } catch { connection.Close(); throw; } } /// <summary> /// 返回结果集中的第一行第一列,忽略其他行或列 /// </summary> /// <param name="cmdText"></param> /// <param name="commandParameters">传入的参数</param> /// <returns></returns> public object ExecuteScalar(string cmdText, params object[] p) { SQLiteCommand cmd = new SQLiteCommand(); using (SQLiteConnection connection = GetSQLiteConnection()) { PrepareCommand(cmd, connection, cmdText, p); return cmd.ExecuteScalar(); } } /// <summary> /// 分页 /// </summary> /// <param name="recordCount"></param> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="cmdText"></param> /// <param name="countText"></param> /// <param name="p"></param> /// <returns></returns> public DataSet ExecutePager(ref int recordCount, int pageIndex, int pageSize, string cmdText, string countText, params object[] p) { if (recordCount < 0) recordCount = int.Parse(ExecuteScalar(countText, p).ToString()); DataSet ds = new DataSet(); SQLiteCommand command = new SQLiteCommand(); using (SQLiteConnection connection = GetSQLiteConnection()) { PrepareCommand(command, connection, cmdText, p); SQLiteDataAdapter da = new SQLiteDataAdapter(command); da.Fill(ds, (pageIndex - 1) * pageSize, pageSize, "result"); } return ds; } #region 静态字段和属性 const short WAIT_TIME = 5; static readonly object locker = new object(); static Dictionary<string, int> _dbThreadIdDict = new Dictionary<string, int>(); /// <summary> /// 获得写操作的超时时间,单位为毫秒,可以通过配置文件appSettings节中添加设置 SQLiteWriteLockTimeout 的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒 /// 默认的超时时间是1000ms /// </summary> public static int SQLiteWriteLockTimeout { get { string configValule = "300000"; if (!string.IsNullOrEmpty(configValule)) { return int.Parse(configValule); } return 1000; } } #endregion private string _connString; public SQLLiteDBHelper() { } #region 私有方法 private void AcquireWriteLock() { if (Connectionstring=="") { return; } _connString = Connectionstring; int threadId = Thread.CurrentThread.ManagedThreadId; int waitTimes = 0; while (_dbThreadIdDict.ContainsKey(_connString) && _dbThreadIdDict[_connString] != threadId) { Thread.Sleep(WAIT_TIME); waitTimes += WAIT_TIME; #if DEBUG Console.WriteLine(_connString + " wait for " + waitTimes + " ms"); #endif if (waitTimes > SQLiteWriteLockTimeout) { //throw new TimeoutException("SQLite等待写操作超时"); } } lock (locker) { if (!_dbThreadIdDict.ContainsKey(_connString)) _dbThreadIdDict.Add(_connString, threadId); } } private void ReleaseWriteLock() { lock (locker) { if (_connString!=null) { if (_dbThreadIdDict.ContainsKey(_connString)) { _dbThreadIdDict.Remove(_connString); } } } } #endregion #region IDisposable 成员 public void Dispose() { ReleaseWriteLock(); } #endregion } }

      

  • 相关阅读:
    获取图片的大小(宽高):BytesIO
    python中url解析 or url的base64编码
    [extjs5学习笔记]第三十七节 Extjs6预览版都有神马新东西
    【翻译】Ext JS 6早期访问版本发布
    【翻译】Ext JS 6有什么新东西?
    【Java二十周年】Delphi转行java的一些小感触
    Cursor类取出数据
    通过服务修改widgetUI
    安卓笔记--Style的继承
    [ExtJS5学习笔记]第三十六节 报表组件mzPivotGrid
  • 原文地址:https://www.cnblogs.com/wangnannan/p/3455213.html
Copyright © 2011-2022 走看看