事务,就像无间道中的一句话:如果到达不了终点,那就回到原点。
事务的acid
- 原子性atomicity:事务中的命令要么全部执行要不全部不执行。即无间道的那句话。
- 一致性consistency:数据库中数据逻辑的一致性。原子性保证了一致性。
- 隔离性isolation:事务和事务之间是隔离的。隔离级别的实现原理是锁机制,比如共享锁在读的时候不允许修改数据,排他锁在修改的时候不允许修改数据,以下根据四个隔离级别,简单介绍一下不同级别下的锁是什么级别:
readUncommited:读未提交。在写的时候允许读。
readCommited:读已提交。在写的时候不允许读。
readReaptable:可重复读。在读的时候不允许修改。
serielizable:串行化。在读的时候不允许修改、插入、删除。
- 持久性durability:事务提交后,数据不可回滚。
redis事务acid
- 原子性:redis入队失败会回滚,但是写入错误会放过,而不会回滚。
- 一致性:非强一致性。
- 隔离性:redis本身是单线程,天生具有隔离性。
- 持久性:redis持久化策略AOF/RDB都是异步的,不保证持久性。
redis事务实现方法
redis事务是通过MULTI,EXEC,DISCARD和WATCH四个原语实现的。
WATCH更像是一把乐观锁,watch key1 之后的时间内,如果key1被非事务操作修改过了,那么事务的批量操作就会失败。
例子1:流程
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET key1 1
QUEUED
127.0.0.1:6379> HSET key2 field1 1
QUEUED
127.0.0.1:6379> SADD key3 1
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (integer) 1
3) (integer) 1
例子2:discard
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET key1 1
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> EXEC
(error) ERR EXEC without MULTI
例子3:入队错误回滚
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set key1 1
QUEUED
127.0.0.1:6379> HSET key2 1
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> SADD key3 1
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
例子4:执行错误放过
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> HSET key1 field1 1
QUEUED
127.0.0.1:6379> HSET key2 field1 1
QUEUED
127.0.0.1:6379> EXEC
1) (error) WRONGTYPE Operation against a key holding the wrong kind of value
2) (integer) 1
例子5:watch乐观锁
127.0.0.1:6379> WATCH key1
OK
127.0.0.1:6379> set key1 2
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set key1 3
QUEUED
127.0.0.1:6379> set key2 3
QUEUED
127.0.0.1:6379> EXEC
(nil)