1.事务的基本特性(ACID)
1)Atomicity(原子性)
事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。 事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
2)Consistency(一致性)
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。 一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。 也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant). 以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个, 比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性.
3)Isolation(隔离性)
一个事务的执行不能被其他事务干扰。隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内, 执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
4)Durability(持续性/永久性)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,不会被回滚。
2.redis基本事务
redis的基本事务需要用到multi命令和exec命令,这种事务可以让一个客户端在不被其他客户端打断的情况下执行多个命令。和关系数据库那种可以在执行的过程中进行回滚的事务不同,在Redis里面,被multi和exec命令包围的所有命令会一个接一个地执行,直到所有命令都执行完毕为止。当一个事务执行完毕之后,Redis才会处理其他客户端的命令。
注意:在一个redis事务中,如果出现了错误,那么事务中的其他操作怡然会执行,与关系型数据库不同,不支持回滚
redis基本事务只满足了事务的基本原则中的I和D原则,A和C原则没有满足
3.增强版redis事务
为了满足事务的其他原则,可以利用redis中的watch命令。watch命令对键进行监视之后,直到用户执行exec命令的这段时间里面,如果有其他客户端抢先对任何被监视的键进行了替换,更新或删除等操作,那么当用户尝试执行exec命令的时候,事务将失败并返回一个错误(之后用户可以选择重试事务或者放弃事务),用秒杀业务做个例子:
watch监视商品的库存,若在事务执行过程中,如果有其他线程更改了商品的库存,那么事务将失败,即秒杀失败。
虽然可以解决一部分问题,但是,在库存大于0的情况下,大量用户的请求失败了,需要重新秒杀,这样的用户体验是很差的,而且,无法解决超卖的问题,因此redis秒杀业务需要自己实现悲观锁或者利用lua脚本来实现原子性从而实现秒杀。
4605





