1.spring中的事务只是事务管理器,具体的事务实现还是在对应的数据库中实现的;
2.在我们日常的代码开发中,只有在某个方法声明了要开启事务,我们才会去做事务管理也才会去和数据库的事务特性和隔离性 相关;如果在spring不开启事务通过dao调用sql就完全和事务无关了,当然你也可以单独在sql中写入事务相关sql语句。
3.spring我们常用的是声明式事务,也就是注解@Transactional
注解有2大参数,分别对应事务隔离级别和事务传播级别。这两个都是基于mysql的事务特性而来的。
(spring的事务注解是依赖于aop原理的,底层引用jdk动态代理和cglib代理)
(jdk动态代理:通过接口来代理)
(cglib动态代理:通过继承目标类来代理)
具体详情下次开个单章专门讲讲
mysql事务隔离级别:
4.mysql的事务特性:原子性、一致性、持久性、隔离性
原子性:事务是完完整整的成功或失败;
一致性:事务完成后数据的准确性,不会因为事务导致数据丢失等;
持久性:事务提交后,数据会持久化到数据库;
隔离性:各个事务之间的隔离(细分四个隔离级别)
5.mysql的隔离级别:读未提交、读已提交、可重复读、串行读,其中mysql默认是可重复读级别;
四种隔离级别可能会造成的问题有:脏读、不可重复读、幻读。
隔离级别 | 隔离级别的值 | 导致的问题 |
Read-Uncommitted | 0 | 导致脏读 |
Read-Committed | 1 | 避免脏读,允许不可重复读和幻读 |
Repeatable-Read | 2 | 避免脏读,不可重复读,允许幻读 |
Serializable | 3 | 串行化读,事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重 |
spring事务隔离级别:(基本和mysql的隔离级别相同)
常量 | 解释 |
ISOLATION_DEFAULT | 这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。 |
ISOLATION_READ_UNCOMMITTED | 这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。 |
ISOLATION_READ_COMMITTED | 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。 |
ISOLATION_REPEATABLE_READ | 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 |
ISOLATION_SERIALIZABLE | 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。 |
spring事务传播属性:(假设A方法调用B方法,B方法的事务注解的传播属性如下)
PROPAGATION_REQUIRED | (Spring 默认的事务的传播) A有事务,B就加入A的事务,如果A没有事务B就新建事务 |
PROPAGATION_REQUIRES_NEW | A有事务就把A事务挂起B新建事务,A没有事务也是B新建事务。新建的B事务将和被挂起的A事务没有任何关系,是两个独立的事务,外层事务失败回滚之后,不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获,也可以不处理回滚操作 |
PROPAGATION_SUPPORTS | A有事务,B就加入A的事务,如果A没有事务,B就以非事务方式执行。 |
PROPAGATION_MANDATORY | A有事务,B就加入A的事务,如果A没有事务,就抛出异常。 |
PROPAGATION_NOT_SUPPORTED | B以非事务方式执行操作,如果A存在事务,就把A事务挂起。 |
PROPAGATION_NEVER | B以非事务方式执行,如果A存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。 (这个是抄人家的,没用过,不清楚~~) |