如果你研究到库存系统的开发问题时,你就会从这里出发考虑了一些有关库存信息中需要的操作和,一般的情况下会遇到的mysql事务处理问题。特别是关于数据表锁定问题,一旦出现并发现象的时候,我们如何保证数据的完整性,值得我们考虑。
事务操作,要保证的三个原则性:
原子性(atomicity):事务是一个原子操作单元,其对数据的修改,要么全部执行,要么全都不执行;
一致性(consistent):在事务开始和完成时,数据都必须保持一致状态;
隔离性(isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行;
持久性(durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
于是,我们假设两个对象a和b
并发对象a 和b
初始状态数据表查询结果:
事务开始的顺序 a->b
a:开始事务
此刻没有提交进行commit
在此状态下b开始了自己的mysql事务处理:
显然,在a没有进行commit行为的时候,b的事务中的动作无法完成,一直处于事务等待阶段,前提是在没有超出时限,b的动作无法提交。
此刻,如果a进行commit:
此刻 b的动作中,由等待的
转变到
说明a完成事务开始解锁,b事务可以进行,但是此刻b事务没有提交(commit)
注意:在这里我们进行两个操作,就是两个对象进行查询
a的查询:
依然存在id为1的这项,原因是b的结果没提交,但a依旧可以读该项数据,但是数据为删除前的数据。
但是,对照b的查询:
可以知道,b对象结果已经在处理了,只是没有提交解锁。
分析可以知道,a读的是b没有提交前的结果集合,但b读的是自己操作的结果集,当b完成提交的时候
此刻,a的结果集合
发现现在状态下和b的集合一样,a=b,这也是在理论值的范围内的。
由此,可以发现其实mysql锁的简单性,当然,也说明当数据库进行锁操作时候,只能是写操作控制,对于读数据,往往只能访问到修改前的数据,这部分数据常常被称为”dirty”或脏数据。在现实中,我们常常是有这样的需求,当a进行写操作时候,期望b不要读数据,是对读行为的控制。
这样保证并发的时候不要出现b查的时候有,但是这个过程正好是a进行写操作的过程,虽然加锁防止并发写,但是却把对于b来说他在此过程中所看到的数据将被修改,即等a完成写操作的时候,b读的数据将被丢弃,这样说来b读到的数据应该是脏数据,或是无效数据,除非a的动作因为某些原因导致事务回滚,操作失败,这样现实数据结果和b看到的一致的时候,才断定b看到的是有效数据,而不是脏数据或是无效数据。