Skip to content
xuexs edited this page Apr 28, 2015 · 1 revision

概念

事务一般应用在对数据准确性要求比较敏感的场合,所以在业务数据上,未必所有数据库的操作都需要使用到此“模拟事务”。

对可能需要用到事务的表,要求有如下几个公共的字段:

序号 字段 说明
1 _id 标识列,即使不同的表,此id也不应该具有相同的值
2 _dataLock 锁标记
3 _dataLockTime 上锁时间,超过1分钟后自动解锁,依据是数据库操作超时达1分钟,基本是有问题
4 _dataVersion 数据版本号
5 _transactionId 事务id
6 _isDelete 是否已经删除

对可能需要用到事务的表,要求有结构几乎一样的备份表,此备份表的作用不单止可以用于模拟事务,结合事务表,还能用于数据的回滚

而对于备份表来讲,不管添加、修改还是删除数据,实际上的操作都为“添加”操作

备份表之所以说是几乎一样,是因为记录原是表的id列名字变为“__id(左边双下划线)”,而备份表的“_id”作为备份表的标识列。

对可能需要用到事务的表,要对select操作增加一些复杂程度,但复杂性可以进行一致性的封装,实际对查询的时间影响其实很小。

事务与步骤表Transation

字段 说明
_id 标识列
transactionId 事务编号
tableName 关联表
dataId 关联表某条数据的id
fullKey transactionId+’_’+ dataId(用于索引数据)
operationType 操作类型
creatTime 添加时间
creatUserId 添加用户,可以为null
status 事务状态

###实现流程

**事务的要求:**假设在任何环节出现问题,即使服务器突然断电还没把事务执行完毕,对用户来说,数据也能恢复到上一次准确的数据。

步骤 说明
1 统计要对多少行数据进行操作(transationStepCount),生成事务id(与_id的生成规则一样即可)
2 把相关数据存放到Base. Transation
成功-go on ;失败-提示用户
3 开始操作第1条数据
判断是否被锁定,而且锁定时间未过(如果是insert操作,则跳过此步)
否-go on;是-提示用户暂时不能修改此数据
锁定当前数据(如果是insert操作,则跳过此步)
操作数据,其他自动状态:
{
_dataLock:true
_dataLockTime: Transation. creatTime
_dataVersion: Transation. _id
}
成功-操作下一条数据;失败-中断事务,尝试恢复数据,提醒用户
……
4 全部成功
5 对每一条事务数据,在备份表增加一条备份数据
6 最后更新Transation的status为true
成功-提示成功;失败-提醒用户,并尝试恢复数据

如上面的过程,操作失败在任何环节都可能发生。那在最极端的情况下,如何数据回滚,下面过程是数据恢复的核心,这个理解后,其他情况就简单了:

步骤 说明
1 查询数据
2 根据当前数据的_transactionId到Transation查询最近的一次事务情况,检查事务的status是否为true
3 当为false的时候
4 根据事务的关联性,尝试恢复数据
5 即使本条数据恢复失败,也从备份表把上一次正常的数据作为查询结果返回给用户

###总结

以上内容初看是复杂,逻辑上走得通,但要求编写数据库核心操作部分需要很高的严谨性,此操作方法写得好,对于上层的使用,还是传统的,调用insert、update和delete的操作。


by shiqiren 未经作者允许,不得转载 Email:shiqirenworld@qq.com