求教育,sqlite 并发多个程序并发访问,需要加锁吗

您好,欢迎来到!
当前位置:&>&&>&应当使用 SQLite 的五个原因
应当使用 SQLite 的五个原因
11:53:35&&
人气:1355次&&评论(0)
所属标签:
SQLite 是非常优秀的数据库,能够在真实的生产环境中完成一些真正的工作。本文将列出五个我认为在2016年应当选用 SQLite 的原因。便于管理不知你是否管理过 Postgres 数据库?想要确保数据库服务器正确配置,需要了解不少东西,比如共享缓存、有效缓存大小、work mem、work mem 的维护以及 wal 缓存等等。此外升级的过程也很恐怖,使用者需要先将数据库离线,运行程序来升级,然后祈祷在重新打开时能正常运作。另外,postgres 数据库具体在哪里呢?你能否指着某个地方说:“那就是我的数据库?”虽然我们都知道,在很多情况下只有 Postgres(或 MySQL、Oracle、SQL Server 等)对应用的某些需求很有效果,不过这不是本文的讨论范围,本文只想强调管理 SQLite 数据库与传统数据库服务器之间的区别。SQLite 便于管理――只有单个文件(有时候是一个文件+事务日志),这个文件的格式在多个主要版本中都是通用的,也就是说如果我有一个3.0.0版本(2004年)的 SQLite 数据库文件,便可以在最新的 SQLite 3.10.0上使用。如果想要在别处使用这个数据库文件,也只需复制到U盘里,甚至存放到云存储中。如果想要每天晚上进行备份,只需将此数据库文件同步到 S3。如果想要与同事分享我的数据分析,也只需给他们发送一份数据库文件备份即可。这个数据库的一大特性就是只有单文件,且文件格式多年以来非常稳定。此外,SQLite 配置起来也很简单,其功能有两种管理方式:编译标识以及编译指示语句(运行时配置)。没有什么配置文件,只需使用想要的功能来构建相应的库,然后在建立数据库连接时配置运行时选项即可。稳定性坚如磐石,且还在不断提高目前有一些优秀的大牛工程师正在积极地进行 SQLite 的开发,使得 SQLite 新增高质量新功能的速度十分惊人。就在最近,SQLite 还加入了 json1 扩展程序以支持 JSON 数据。SQLite 还发布了一个全文搜索扩展包的改进版,其中包括使用 BM25 算法对结果进行排序。除了新增功能之外,SQLite 的开发者也在努力改进 library 的性能,在3.8.11版本的发布说明中,包含这些宣传内容:新版本 SQLite,运行速度是3.8.0版本的两倍,是3.3.9版本的三倍。尽管一直在更新和改进,SQLite 却很少有新增的 bug。SQLite 的测试套件公认是业内最好的测试套件之一,而“ SQLite 是如何测试的”相关文档也被频繁推荐到 HackerNews 上。可扩展性与可控性笔者最喜爱 SQLite 的地方是它的可扩展性,SQLite 是应用嵌入式的,它与应用运行在同一个地址空间中,并能代表你执行应用代码。在 Python 标准库中,无论是 SQLite 驱动的 pysqlite ,还是可选驱动 apsw 都为自定义 SQL 函数、聚合函数与排序规则提供了相应的 API;apsw 更进一步,为定义虚拟表和虚拟文件系统提供了相应的 API。在实际案例中,假设表格中有一列用于存储 URL,你还想确定最常见的主机名是哪些――如果使用不同的数据库,就必须编写复杂的正则表达式(字符串操作函数组),或者将数据从应用中抽出来,然后在代码中进行计算。使用 SQLite 的话,就可以在 Python 中定义主机名,并使用它来创建简单的 COUNT 查询:from&urlparse&import&urlparsedef&hostname(url):return&urlparse(url).netloc
conn&=&sqlite3.connect('my-database.db')
conn.create_function('hostname',&1,&hostname)&&#&name,&num_params,&funcSELECT&hostname(mytable.url),&COUNT(mytable.id)&AS&ctFROM&mytableGROUP&BY&hostname(mytable.url)ORDER&BY&ct&DESC;还可以创建聚合函数,输入0……n的值,生成单独的输出值。样例可能包括:计算标准差、通过处理值来生成字符串、进行某种类型的分类等。虚拟表目前仅受 apsw 支持,用户可以在代码中定义表格,并将其当作普通的 SQL 表格查询,即便后台数据是完全动态的。比如,我编写了一个简单的虚拟表格,允许用户将其当作 SQL 表格来查询 Redis。你也可以编写同名函数,返回0……n行结果,比如正则表达式:处理输出内容,并生成一行行匹配 token。实际上,SQLite 的各个方面都可以受应用的控制。快如闪电SQLite 速度非常快,它运行在同一台机器上,因此在执行查询或读取结果时并不产生网络开销。由于与应用运行在同一个地址空间中,因此并无连接协议、序列或通过 unix socket 通讯的需求。SQLite 也可以在资源匮乏、要求高效率的移动设备上运行,并支持大量的编译标记:允许用户移除没有计划使用的功能。SQLite 的速度弥补了它的最大缺点之一:写入时数据库文件锁定。通过快速写入数据,只有当有大量的并发写入时,数据库锁定才会成为问题。WAL模式SQLite 的3.7.0发布版增加了新的日志记录方法:使用预写日志。单独来看这个消息并不太吸引人,但对于 web 应用开发者来说(或者要应付并发问题的开发者来说),这意味着读取并不会再阻碍写入了,反之亦然。或者换句话说,读取和写入能够并发进行。没有 WAL 模式的话,想要写入数据库则要求写入程序独占数据库的访问权,在写入完成前无法读取。下面是一个样例,说明了两者的不同。假设我们有两个进程,一个写入、一个读取。写入程序开启了独占事务(表明打算写入);读取程序开启事务;读取程序尝试发布SELECT语句:Journal&mode&=&&delete&&(the&default):
Writer:&BEGIN&EXCLUSIVE
Reader:&BEGIN
Reader:&SELECT&*&FROM&&Error:&database&is&lockedJournal&mode&=&&wal&:
Writer:&BEGIN&EXCLUSIVE
Reader:&BEGINReader:&SELECT&*&FROM&&Returns&table&contents然而值得注意的是:即使不启用 WAL 模式,写入通常在几毫秒中发生。这个时间太短了,用户只会在并发很高或者写入事务用时很长时才会注意到这个问题。额外的原因:BerkeleyDB由于只需锁定单独页面,而无需锁定整个数据库,集成了 SQLite 的 BerkeleyDB 可以给需求数据库并发访问的应用开发者有更好的体验。而且这样一来,BerkeleyDB 在并发数据库负载的情况下也能更高效地扩展,使得各事务无需争夺同一个页面内的数据。BerkeleyDB 还支持多版本并发控制(MVCC),使得读取操作也可以继续在写入操作的同一个页面进行。另外,BerkeleyDB 还有一个优势就是效率更高。BerkeleyDB 的 SQL 接口是作为 SQLite 的简易替代,所支持的API与功能是相同的。BerkeleyDB 还提供了一些额外的功能,比如复制(SQLite 有备份程序,但在我看来效果不如 BDB 的强大)、加密,当然还有 BerkeleyDB 自身的所有功能。使用 BerkeleyDB 主要的缺点在于:它对配置数值非常敏感,而了解正确的页面大小、缓存大小以及其他设置参数需要对相关知识有较深的了解。另一个缺点是证书问题:关于 BerkeleyDB 的证书问题请参考&Oracle 的证书页面。总结我希望你们尝试一下 SQLite,别相信守旧者的说法:什么不适用于生产环境,或者不适合用在 web 应用中。
热门活动:
阅读:1355次
网友评论&登录后发表评论,让更多网友认识您!查看: 7720|回复: 21
sqlite3 多进程访问 数据库被锁
签到天数: 10 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
本帖最后由 qiaofeng129 于
14:36 编辑
sqlite3 多进程访问 数据库被锁&&,这个问题大家有没有什么解决方法那?
签到天数: 14 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
public synchronized& && && && && && && && && && && && && && && && &
多进程 加这个没用&
签到天数: 1 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
同楼上。。&&dao方法前面加上 public synchronized&&XXX
该用户从未签到主题帖子e币
public synchronized
多进程 加这个没用
多个线程 访问共享资源,就这个方法&
签到天数: 14 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
多进程 加这个没用
多个线程 访问共享资源,就这个方法
该用户从未签到主题帖子e币
加个multi progress属性试试
签到天数: 19 天连续签到: 1 天[LV.4]偶尔看看III主题帖子e币
加锁,这个肯定是代码写的有问题。毕竟所线程,还是很有难度的。
签到天数: 2 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
加上同步锁或判断是否被锁,稍等一会在执行
该用户从未签到主题帖子e币
多线程操作本来就有风险,很考验技术,我没有太多的使用经验
不过建议你还是用线程锁进行操作,尽管是共享资源,但是要保证这个资源只有一个线程操作就好啊。
签到天数: 17 天连续签到: 1 天[LV.4]偶尔看看III主题帖子e币
被锁、、应该是还有方法在操作数据库然后,你去访问的时候他是被锁的 就不让你访问了直到,前一个方法退出数据库才会解锁。(根据自己对数据库的一点模糊的映像,应该是他的原子性导致的),所以最好是做一个统一的管理数据库的类,所有的对数据库的操作都用它来控制。操作完后即使的退出来。
该用户从未签到主题帖子e币
得加上事务!把你的log贴出来
该用户从未签到主题帖子e币
可以结贴了.单例+同步锁,同步锁是针对对象的,如果是不同对象,同步方法肯定没用
那如果一个程序多个进程呢&
那如果一个程序多个进程呢&
签到天数: 10 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
可以结贴了.单例+同步锁,同步锁是针对对象的,如果是不同对象,同步方法肯定没用 ...
那如果一个程序多个进程呢
签到天数: 10 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
可以结贴了.单例+同步锁,同步锁是针对对象的,如果是不同对象,同步方法肯定没用 ...
那如果一个程序多个进程呢
我都说了单例啊,你要记住同步关键字始终是针对于对象的,如果你对象是唯一的,自然就同步了.&
该用户从未签到主题帖子e币
那如果一个程序多个进程呢
我都说了单例啊,你要记住同步关键字始终是针对于对象的,如果你对象是唯一的,自然就同步了.
单例只针对同个进程&
圣诞限量勋章
圣诞限量勋章
QQ已认证,此人靠谱
社区认证会员
社区认证会员
推荐阅读热门话题
61886420384328281281261252226218210208204201715
23&分钟前半小时前半小时前1&小时前1&小时前5&小时前5&小时前5&小时前5&小时前昨天&23:57昨天&10:32昨天&10:24昨天&08:22前天&23:45前天&20:38前天&09:06
Powered byPYTHON访问sqlite数据库 问题
?求教育~【python吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:137,792贴子:
PYTHON访问sqlite数据库 问题
?求教育~收藏
试着用PYTHON访问sqlite数据库,成功连接后进行
查看表的所有信息SQL操作但是结果缺只能查看表的第一条记录
并且中文乱码 求教育~~结果
51CTO学院11年行业品牌,1400万用户选择,中国专业IT技能学习平台,python.通过在线学习的方式,帮助广大技术人员实现技能提升,高薪就业的职业梦想,python.
没错fetchone()方法只获取一条记录。取所有记录用fetchall()方法。每条记录是一个list对象,用for把每条记录的每个列取出来,加decode才不会乱码。
用encode和decode。先转成unicode再转gbk
# -*- coding: utf-8 -*-import sqlite3con = sqlite3.connect(&:memory:&)con.isolation_level = Nonecur = con.cursor()print &##### DO CREATE TABLE #####&# 创建表.cur.execute(&create table test(id INT,
value varchar(10) )&)print &##### DO INSERT #####&# 插入数据.cur.execute(&insert into test(id, value) values (1, '北京')&)cur.execute(&insert into test(id, value) values (2, '上海')&)cur.execute(&insert into test(id, value) values (3, '广州')&)cur.execute(&insert into test(id, value) values (4, '重庆')&)cur.execute(&insert into test(id, value) values (5, '深圳')&)# 查询.cur.execute(&select * from test&)allResult = cur.fetchall()# 逐行输出.print &Every Row & Col&for line in allResult:
print &ID = & +
str(line[0]) + &; Value = & + line[1].encode(&GBK&)print &##### DO UPDATE #####&# 更新.cur.execute(&UPDATE test SET value = '帝度' WHERE id = 1&)cur.execute(&UPDATE test SET value = '魔度' WHERE id = 2&)# 查询核对.cur.execute(&select * from test&)allResult = cur.fetchall()print &Every Row & Col&for line in allResult:
print &ID = & +
str(line[0]) + &; Value = & + line[1].encode(&GBK&)print &##### DO DELETE #####&cur.execute(&DELETE FROM test WHERE id IN (1,3,5)&)cur.execute(&select * from test&)allResult = cur.fetchall()print &Every Row & Col&for line in allResult:
print &ID = & +
str(line[0]) + &; Value = & + line[1].encode(&GBK&)# 关闭连接.con.close()执行结果:##### DO CREATE TABLE ########## DO INSERT #####Every Row & ColID = 1; Value = 北京ID = 2; Value = 上海ID = 3; Value = 广州ID = 4; Value = 重庆ID = 5; Value = 深圳##### DO UPDATE #####Every Row & ColID = 1; Value = 帝度ID = 2; Value = 魔度ID = 3; Value = 广州ID = 4; Value = 重庆ID = 5; Value = 深圳##### DO DELETE #####Every Row & ColID = 2; Value = 魔度ID = 4; Value = 重庆
25万能在上海买什么?一辆中档车?一块名牌表?
假如你有25万,你会怎么花?
会不会选择买一套精装loft?让自己在上海安个家!
会不会将目光锁定在嘉定?购买一套38—56㎡轨交loft公寓?
4.5米挑高双层2+1房,宜买宜卖宜出租,总价49万起!
上海租房族,也能轻松实现买房梦!圆梦地址:
你所认为的乱码只是你认为的而已~
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或几个人同时在使用sqlite 数据库的程序
卡住了 出错误。 - 其他数据库当前位置:& &&&几个人同时在使用sqlite 数据库的程序
卡住了 出错几个人同时在使用sqlite 数据库的程序
卡住了 出错误。&&网友分享于:&&浏览:62次几个人同时在使用sqlite 数据库的程序
卡住了 出异常。。。一直没说清楚 其实就是并发的问题
有一个操作是得到结合结果
耗时比较长 这个其他人操作。。。各种卡住。。。------解决方案--------------------
SQLite对于并发的处理机制是允许同一个进程的多个线程同时读取一个数据库,但是任何时刻只允许一个线程/进程写入数据库。所以必须要对数据库的读写来进行控制SQLite的FAQ(7) 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗?多进程可以同时打开同一个数据库,也可以同时 SELECT 。但只有一个进程可以立即改数据库。SQLite使用读/写锁定来控制数据库访问。(Win95/98/ME 操作系统缺乏读/写锁定支持,在低于 2.7.0 的版本中,这意味着在 windows 下在同一时间内只能有一个进程读数据库。在版本 2.7.0 中 这个问题通过在 windows 接口代码中执行一个用户间隔几率读写锁定策略解决了。) 但如果数据库文件在一个 NFS 文件系统中,控制并发读书的锁定机制可以会出错。因为 NFS 的fcntl() 文件锁定有时会出问题。如果有多进程可能并发读数据库则因当避免把数据库文件放在 NFS 文件系统中。 根据微软的文档,如果不运行 Share.exe 后台程序则 FAT 文件系统中的锁定可能不工作。对 Windows 非常有经验的人告诉我网络文件的锁定有许多问题并且不可靠。如果是这样,在2个或以上 Windows 系统中共享一个 SQLite 数据库文件会导致不可预知的问题。我们知道没有其他的嵌入式 SQL数据库引擎比SQLite支持更多的并发性。 SQLite允许多进程 同时打开和读取数据库。任何一个进程需要写入时,整个数据库将在这一过程中被锁定。但这一般仅耗时 几毫秒。其他进程只需等待然后继续其他事务。其他嵌入式SQL数据库引擎往往只允许单进程访问数据库。但是,client/server型的数据库引擎 (如 PostgreSQL, MySQL, 以及 Oracle) 通常支持更高的并发度, 并支持多进程同时写入同一个数据库。由于总有一个控制良好的服务器协调数据库的访问,这才保证了以上 特性的实现。如果你的应用需要很高的并发度,你应该考虑使用client/server数据库。事实上,经验告诉 我们大多数应用所需要的并发度比他们的设计者们想象的要少得多。当 SQLite 尝试操作一个被另一个进程锁定的文件时,缺省的行为是返回 SQLITE_BUSY。你可以用 C代码更改这一行为。 使用 sqlite3_busy_handler() 或sqlite3_busy_timeout() API函数。如果两个或更多进程同时打开同一个数据库,其中一个进程创建了新的表或索引,则其它进程可能不能立即看见新的表。其它进程可能需要关闭并重新连结数据库。--------------------------------------------(8) SQLite是线程安全的吗?有时候是的。为了线程安全,SQLite 必须在编译时把 THREADSAFE 预处理宏设为1。在缺省的发行的已编译版本中 Windows 版的是线程安全的,而 Linux 版的不是。如果要求线程安全,Linux 版的要重新编译。“线程安全”是指二个或三个线程可以同时调用独立的不同的sqlite3_open() 返回的&sqlite3&结构。而不是在多线程中同时使用同一个 sqlite3 结构指针。一个sqlite3结构只能在调用 sqlite3_open创建它的那个进程中使用。你不能在一个线程中打开一个数据库然后把指针传递给另一个线程使用。这是因为大多数多线程系统的限制(或 Bugs?)例如RedHat9上。在这些有问题的系统上,一个 线程创建的fcntl()锁不能由另一个线程删除或修改。由于SQLite依赖fcntl()锁来进行并发控制,当在线程间传递数据库连接时会出现严重的问题。也许在Linux下有办法解决fcntl()锁的问题,但那十分复杂并且对于正确性的测试将是极度困难的。因此,SQLite目前不允许在线程间共享句柄。在UNIX下,你不能通过一个 fork() 系统调用把一个打开的 SQLite 数据库放入子过程中,否则会出错。
------解决方案--------------------
同时使用并不是问题啊,但同时写入就会产生冲突,你的实现情况是什么?
------解决方案--------------------
创建临时表的指令是什么? 你使用的相同表名?
------解决方案--------------------探讨临时表 用id区分了
是不是sqlite 不适合 几个人 同时使用
------解决方案--------------------多进程访问,需要保证写入前加排它锁。
------解决方案--------------------楼上广告,顺便顶下。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有}

我要回帖

更多关于 sqlite 并发访问 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信