事务ACID: 原子性、一致性、隔离性、持久性
一、事务传播属性:
类别 |
未嵌套其他事务 |
已嵌套其他事务 |
其他 |
NEVER |
无事务 |
抛出异常 |
|
NOT_SUPPORTED |
无事务 |
其他事务挂起, 直到本方法结束后,该事务才恢复 |
本类别的方法内部不能增删改 本类别不需要事务,故而在查询时性能高。
|
SUPPORTS |
无事务 |
加入该事务 |
|
REQUIRED (默认) |
创建一个事务 |
加入该事务
|
是默认类别 |
REQUIRES_NEW |
创建一个事务 |
其他事务挂起,创建一个事务, 直到本事务结束,该事务才恢复 |
|
MANDATORY |
抛出异常 |
加入该事务 |
|
事务必要性排名:
未嵌套:NEVER= NOT_SUPPORTED= SUPPORTS (无) < REQUIRED=REQUIRES_NEW (新建)< MANDATORY (异常)
有嵌套:NEVER (异常)< NOT_SUPPORTED (无)<SUPPORTS= REQUIRED = MANDATORY (加入) < REQUIRES_NEW (新建)
二、事务并发问题
在同一个事务中发生以下情况:
脏读 |
读到另外事务未提交的数据 |
不可重复读 |
多次读取同一记录,其结果不一样。原因是数据已更新。 |
幻读 |
多次读取,发现某条记录没了,或者新增了某条记录。重点在新增或删除 |
三、事务的隔离级别
隔离级别 |
特点 |
读未提交 |
会脏读、不可重复读、幻读 |
读已提交 (默认) |
会不可重复读、幻读 |
可重复读 |
会幻读 |
串行化 |
无并发问题,但是性能低下 |
四、锁的类别
锁类别 |
加锁时机 |
其他事务读 |
其他事务写 |
共享锁 |
读 |
可以 |
不可以 |
排它锁 |
增删改 |
不可以 |
不可以 |
更新锁 |
改 |
可以 |
不可以 |
快照 |
其实不加锁 |
可以 |
可以 |
五、悲观锁和乐观锁
名为"锁",其实不是锁,而是加锁的解决方案。
悲观锁 |
在select的时候加上排它锁,即在select的时候既不能读又不能写 |
乐观锁 |
通过版本号字段 @javax.persist.Version |