本文(其实不止本文,我现在的多数思想都是)多数来源于多于infoQ中一位大神文章的理解。感谢程序员这个行业,everything is opened!If you can,anything will be your's! 再次传播一下,http://www.hollischuang.com。作为一只小白,会有你想要的!
事务的四大特性:原子性、一致性、隔离性、持久性。
事务的隔离现象
脏读:事务A读取了事务B未提交的数据。
不可重复读:事务A两次读取到的数据不一样(事务B在中间进行了修改)。
幻读:事务A两次读到的数据不一样(事务B在中间进行了增删)。
事务的隔离级别
未提交读(read uncommitted):所有隔离级别都会出现。
- 事务在读时不加锁;写加行级共享锁。
提交读(read committed):脏读不会出现,幻读和不可重复读还会出现。
- 事务读取时行级共享锁,读完即释放;写加行级排它锁;事务结束才释放。(因为读时共享的,所以可以A先读,B读且改并提交,A再读就不一样了。)
可重复读(repeatable reads):脏读、不可重复读都不会出现,幻读会出现。
- 事务读取时行级共享锁,事务结束才释放;写加行级排它锁,事务结束才释放。
可序列化(Serializable):所有现象都不会出现。
- 读加表级共享锁;写加表级排它锁。
因为在可序列化的隔离级别中,数据库不能 增删改 同一张表中的两条不同的数据,对于性能有很大的影响,所以MySQL默认的隔离级别是可重复读。
参考:事务的隔离级别。
spring中的事务的传播行为
PROPAGION_XXX :事务的传播行为
- 保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常 - 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
参考:spring中的事务。