1 事务特性ACID
A原子性:当前事务同时成功或同时失败
C一致性:使用事务的最终目的,依赖其它三大特性和业务代码的正确逻辑实现
I隔离性:事务并发执行时,内部能互不干扰;由MySQL的各种锁和MVCC机制实现
D持久性:一旦事务提交,对数据库的影响是永久的,由redoLog日志实现
2 事务的隔离级别
read-uncommitted 读未提交:脏读
read-commit 读已提交:不可重复读
repeatable-read 可重复读:幻读
serializable 串行:解决上述所有问题,包括脏写
MySQL查看当前隔离级别:: show variables like 'tx_isolation'
MySQL设置隔离级别:set tx_isolation=" repeatable-read"
理解可重复读:事务开启后,执行第一条查询语句后,MySQL会生成一个快照,后续的查询操作均基于这个快照ReadView
2.1 脏写(更新丢失)
多个事务同时修改一行数据(通常是在事务中查询到数据,通过Java逻辑修改后,update)(×);解决:使用SQL update(MySQL select是快照读,insert update delete是当前读)
上述锁是悲观锁;可以利用乐观锁:version字段,进行CAS比较,version相同再更新
2.2 幻读
2.3 串行化
对同一条记录的读写是串行执行的
读锁 共享锁 S锁:读锁是共享的,多个事务可以同时加S锁,但不允许其它事务修改;select ... lock in share mode;
写锁 排它锁 X锁:写锁是排它的,会阻塞其它写锁和读锁,update、insert、delete都会加写锁;select ...for update
串行化原理:在事务中对所有的select加读锁;读写互斥,写写互斥
3 如何选择read-commit 读已提交、repeatable-read 可重复读
MVCC机制:
undo多版本数据链:
同一时间维度:RR级别(执行读之后,均用同一的快照);多次查询需要加事务,保证RR
对并发要求高:RC(查询可以不加事务);隔离级别越低,性能越高
4 事务优化原则
4.1 大事务的影响
1 并发情况下,数据库连接池容易崩
2 锁定太多数据,造成大量阻塞和锁超时
3 执行时间长,容易造成主从延迟
4 回滚所需时间长
5 undoLog膨胀
6 容易导致死锁
4.2 事务优化原则
1 查询等操作放在事务外(性能:RC > RR)
2 事务中避免远程调用,远程调用要设置超时,防止事务等待太久
3 事务中避免一次性处理太多数据
4 更新等涉及加锁操作尽量靠后(update靠前,别的事务等待的时间会比较长)
5 能异步处理就异步处理(事务内调用别的接口)
6 业务代码保证数据一致性,非事务执行(性能要求很高的话,可以不用事务;Java代码搞定)一般不建议