SQLite什么都好,就怕“database is locked”这些年来想尽办法去规避它。

测试代码:

static void Test2()
{XCode.Setting.Current.TransactionDebug = true;XTrace.WriteLine(Role.Meta.Count + "");XTrace.WriteLine(Log.Meta.Count + "");Console.Clear();Task.Run(() => TestTask(1));Thread.Sleep(1000);Task.Run(() => TestTask(2));
}static void TestTask(Int32 tid)
{try{XTrace.WriteLine("TestTask {0} Start", tid);using (var tran = Role.Meta.CreateTrans()){var role = new Role();role.Name = "R" + DateTime.Now.Millisecond;role.Save();XTrace.WriteLine("role.ID={0}", role.ID);Thread.Sleep(3000);role = new Role();role.Name = "R" + DateTime.Now.Millisecond;role.Save();XTrace.WriteLine("role.ID={0}", role.ID);Thread.Sleep(3000);if (tid == 2) tran.Commit();}}catch (Exception ex){XTrace.WriteException(ex);}finally{XTrace.WriteLine("TestTask {0} End", tid);}
}

View Code

预热环境以后,我们开了两个任务去执行测试函数,间隔1秒。
测试函数负责插入两行数据,间隔3秒。
第一个任务最后会回滚,第二个任务提交。
显然,两个任务会重叠。

比较好奇,任务1申请得到自增1后,任务2申请得到的自增会是多少?
任务1回滚以后,它所申请得到的自增数字如何处理?

结果:

02:45:03.470  6 Y 5 TestTask 1 Start
02:45:03.470  6 Y 5 Transaction.Begin ReadCommitted
02:45:03.486  6 Y 5 Select Count(*) From Role Where Name='R470'
02:45:03.501  6 Y 5 Insert Into Role(Name, IsSystem, Permission) Values('R470', 0, '');Select last_insert_rowid() newid
02:45:03.517  6 Y 5 开始初始化实体类UserX
02:45:03.517  6 Y 5 完成初始化实体类UserX
02:45:03.533  6 Y 5 role.ID=11
02:45:04.486 14 Y 6 TestTask 2 Start
02:45:04.486 14 Y 6 Transaction.Begin ReadCommitted
02:45:04.486 14 Y 6 Select Count(*) From Role Where Name='R486'
02:45:04.486 14 Y 6 Insert Into Role(Name, IsSystem, Permission) Values('R486', 0, '');Select last_insert_rowid() newid
02:45:05.251 15 Y 7 Transaction.Begin ReadCommitted
02:45:05.251 15 Y 7 Insert Into Log(Category, [Action], LinkID, CreateUserID, CreateTime, Remark) Values('角色', '添加', 11, 0, '2017-01-27 02:45:03', 'ID=11,Name=R470');Select last_insert_rowid() newid
02:45:06.548  6 Y 5 Select Count(*) From Role Where Name='R548'
02:45:06.548  6 Y 5 Insert Into Role(Name, IsSystem, Permission) Values('R548', 0, '');Select last_insert_rowid() newid
02:45:06.548  6 Y 5 role.ID=12
02:45:09.555  6 Y 5 Transaction.Rollback ReadCommitted
02:45:09.555  6 Y 5 TestTask 1 End
02:45:09.618 14 Y 6 SQL耗时较长,建议优化 5,120毫秒 Insert Into Role(Name, IsSystem, Permission) Values('R486', 0, '');Select last_insert_rowid() newid
02:45:09.618 14 Y 6 role.ID=11
02:45:12.633 14 Y 6 Select Count(*) From Role Where Name='R633'
02:45:12.633 14 Y 6 Insert Into Role(Name, IsSystem, Permission) Values('R633', 0, '');Select last_insert_rowid() newid
02:45:12.633 14 Y 6 role.ID=12
02:45:15.649 14 Y 6 Transaction.Commit ReadCommitted
02:45:15.649 14 Y 6 TestTask 2 End
02:45:15.774 15 Y 7 SQL耗时较长,建议优化 10,519毫秒 Insert Into Log(Category, [Action], LinkID, CreateUserID, CreateTime, Remark) Values('角色', '添加', 11, 0, '2017-01-27 02:45:03', 'ID=11,Name=R470');Select last_insert_rowid() newid
02:45:15.774 15 Y 7 Transaction.Commit ReadCommitted
02:45:16.622 16 Y 9 Transaction.Begin ReadCommitted
02:45:16.622 16 Y 9 Insert Into Log(Category, [Action], LinkID, CreateUserID, CreateTime, Remark) Values('角色', '添加', 12, 0, '2017-01-27 02:45:06', 'ID=12,Name=R548');Select last_insert_rowid() newid
02:45:16.622 16 Y 9 Insert Into Log(Category, [Action], LinkID, CreateUserID, CreateTime, Remark) Values('角色', '添加', 11, 0, '2017-01-27 02:45:09', 'ID=11,Name=R486');Select last_insert_rowid() newid
02:45:16.622 16 Y 9 Insert Into Log(Category, [Action], LinkID, CreateUserID, CreateTime, Remark) Values('角色', '添加', 12, 0, '2017-01-27 02:45:12', 'ID=12,Name=R633');Select last_insert_rowid() newid
02:45:16.637 16 Y 9 Transaction.Commit ReadCommitted

从测试结果来看:
1,任务1申请得到11和12,任务2也是
2,任务1申请得到11后,任务2启动,执行到Insert时阻塞了5.12秒,直到任务1回滚了事务
3,线程15和16是异步写日志,显然它们也被阻塞,线程15阻塞10.519秒,知道任务2提交事务

结论:SQLite执行更新事务操作时使用排它锁,强制自增数字同步分配!

参考:
http://sqlite.1065341.n5.nabble.com/Transactions-and-sqlite3-last-insert-rowid-td8905.html

> If I understand it correctly, connection C1 can do an INSERT, get
> ROWID 4, C2 does an INSERT, gets 5, and commits, and then C1 commits,
> with its 4; if C1 rolled back, there's no 4 in the database, just 5
> and whatever else, correct?
>
No, this can't happen. As soon as C1 does its insert, it acquires an
exclusive lock on the database. C2 can't do an insert until C1 either
commits or rolls back and releases the lock. If C1 committed, then C2
will get 5, if C1 rolled back, then C2 will get 4.

我不相信神话,我只相信汗水!我不相信命运,我只相信双手!

SQLite事务与自增深度分析相关推荐

  1. C# SQLite事务操作方法分析

    本文实例讲述了C# SQLite事务操作方法.分享给大家供大家参考,具体如下: 在 C#中执行Sqlite数据库事务有两种方式:SQL代码和C#代码 1. SQL代码: BEGIN- COMMIT / ...

  2. 迈克菲实验室:Flame病毒的深度分析

    今年五月份发现的Flame病毒(又名Flamer.Skywiper或火焰病毒)对伊朗能源部门进行了猛烈的网络***,Flame病毒的出现引起了人们对于网络间谍活动和网络战争的高度关注.伊朗方面认为,F ...

  3. sqlite事务模型、性能优化tips、常见误区

    0,前言 本文主要介绍sqlite的事务模型,以及基于事务模型的一些性能优化tips,包括事务封装.WAL+读写分离.分库分表.page size优化等.并基于手淘sqlite的使用现状总结了部分常见 ...

  4. 深度分析DROP,TRUNCATE与DELETE的区别【我的数据库之路系列】

    深度分析DROP,TRUNCATE与DELETE的区别[我的数据库之路系列] 转载自:http://hi.baidu.com/bjn_wuming/blog/item/8b27a9af36ef26f6 ...

  5. 中国石油化工产业发展环境深度分析及投资价值评估报告2022-2028年版

    中国石油化工产业发展环境深度分析及投资价值评估报告2022-2028年版  业界定与发展环境剖析1.1 石油化工产业界定及产业链梳理 1.1.1 石油化工产业的概念分析 1.1.2 石油化工产业的构成 ...

  6. 2022-2028年中国交通建设PPP模式深度分析及发展战略研究报告(全卷)

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了PPP模式行业相关概述.中国PPP模式行业运行环境.分析了中国PPP ...

  7. 深度分析Java的枚举类型——枚举的线程安全性及序列化问题

    点击关注,快速进阶高级架构师 作者:Hollis 写在前面:Java SE5提供了一种新的类型-Java的枚举类型,关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为 ...

  8. FMDB使用SQLite事务Save Point

    FMDB使用SQLite事务Save Point 在SQLite中,事务提供了批量处理,批量撤销的功能.当批量操作中有一步无法完成操作,就会把执行过的语句都撤销,恢复到撤销前的状态.但是由于SQLit ...

  9. Memcached深度分析【zz】

    Memcached深度分析 Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能.关于这个东西,相信 ...

最新文章

  1. Linux中的Ramdisk和Initrd
  2. .whl文件打开方式 Python
  3. python tracer函数_Python流程控制常用工具和函数定义
  4. yii2 linkpager ajax,Yii2扩展 - LinkPager 带分页大小
  5. AIDE2.6.1安装及配置C/C++开发数据
  6. 【附源码】计算机毕业设计SSM汽车租赁系统
  7. android自定义上拉刷新,Android RecyclerView自定义上拉和下拉刷新效果
  8. t-SNE数据降维可视化
  9. 几个开源即时通讯聊天软件推荐-带源码地址
  10. CentOS7安装FTP服务器及默认21端口修改
  11. 推荐系统系列之隐语义模型
  12. 服务器设置来电自动重启,电脑来电自动重启怎么样设置
  13. windows7旗舰版序列号[经测试,第一枚即可完成升级!]
  14. mysqloffset什么意思_重新认识Mysql的LIMIT OFFSET
  15. 藏宝阁显示角色可买服务器,梦幻西游:刚买角色的藏宝阁上居然有东西,客服说是原号主出售的...
  16. 人脸识别用哪种python库_GitHub - Veechiry/face_collection: python的face_recognition人脸识别库的使用...
  17. Android手机AP模式下本机IP
  18. android ios 垃圾回收,iOS 面试题(16):解释垃圾回收的原理
  19. poj1228Grandpa's Estate
  20. 01-35-springcloud-zk-eureka-consul-cap-父工程

热门文章

  1. 自动化运维-Ansible (第三部:Playbook 介绍)
  2. java学习笔记 --- 多线程(多线程的控制)
  3. linux服务器,ping没问题,http请求经常超时、时好时坏的解决办法
  4. 带命名空间的XML的dom4j应用转
  5. WebBrowser控件使用相关
  6. VMware专家:行动起来 狙击云炒作
  7. 怎么做才能将请求平摊到多台服务器上面去呢
  8. ThinkPHP验证码不能显示如何解决
  9. java七大设计原则,23种设计模式
  10. Redis-Bitmap介绍及使用