1、事务的四大特性:
原子性、
–>由undolog保证,记录了需要回滚的日志信息
一致性
(能量守恒)、
–>由其他三大特性保证
隔离性
(在并发操作中,不同事务不会相互干扰)、
–>由MVCC来保证,MVCC是一种用来解决读写冲突的无锁并发控制,为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳相关联,读操作只读该事务开始前的数据库的快照。解决并发时读写操作不相互阻塞,解决脏读、幻读、不可重复读等事务隔离问题,不解决事务更新丢失问题。
持久性
(事务一旦提交成功,数据必须被持久化到数据库)
–>由redolog来保证,mysq修改数据时会在redolog中记录日志数据,就算数据没有保存成功,只要日志保存成功,数据就不会丢失
2、数据库事务的隔离级别:
读未提交
:一个事务要可读取另一个事务未提交的数据
(会产生脏读:A读取了未提交的新事务,然后新事务又被回滚了,则A读到错误数据)
读已提交
:一个事务要等另一个事务提交后才能读取数据 -> 读写的并发场景下
(会产生不可重复读:A读取了B提交的更新的新事务,即在A的一个事务范围内的多次查询返回了不同数据值) -> 记录行加锁,读的时候不允许修改
可重复读
:事务开启后,就不允许再进行修改操作
(会产生幻读:A读取了B提交的增删的新事务,即在A的一个事务范围内的多次查询返回了不同数据记录)-> 表加锁
串行化事务
:串行化执行
事务丢失(回滚丢失、覆盖丢失)-> 两个事务不能同时进行增删改操作
mysql的默认隔离级别是可重复读;oracle、sqlserver的默认隔离级别是读已提交。
3、spring怎么配置事务
事务管理器 org.springframework.jdbc.datasource.DataSourceTransactionManager property:datasource
编程式事务
:事务管理的模板 org.springframework.transaction.support.TransactionTemplate
基于Aspect声明式事务
的xml配置:
<tx:advice id=”” transaction-manager=””>
<tx:attributes>
<tx:method name=”方法名” isolation=”” propagetion=””/>
</tx:attributes>
</tx:advice>
<aop:config>
<!– 定义切断:哪些类的哪些方法应该增强 –>
<aop:pointcut expression=”execution()” id=”” />
<!– 定义切面 –>
<aop:advisor advice-ref=”” pointcut-ref=”” />
</aop:config>
获取spring容器的上下文:
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); //基于注解
ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”); //基于xml配置文件
开启事务@EnableTransactionManagemen、@Configuration
注解@Transaction
中配置事务的隔离级别及传播特性,注解中可传以下6个属性:
isolation:DEFAULT,事务的隔离级别
propagation:事务的传播特性
read-only:false,不是只读
timaout:-1,事务的超时时间
no-rollback-for:发生哪些异常不回滚
rollback-for:发生哪些异常回滚事务
4、spring事务的传播特性
指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
七个事务隔离级别
:
不要事务
:
never(上层调用方法中有事务就抛异常)、
not_supported(上层调用方法中有事务就将该事务挂起继续运行)
事务可有可无
:
supports(有就用,没有就不用)
必须要有事务
:
requires_new(有没有都新建)、
nested(没有就新建,有就在当前事务中嵌套子事务,子事务不影响父事务(父捕获子方法的异常时),父事务影响子事务)、
required(没有就新建,有就加入当前事务)、
mandatory(有就用,没有就抛异常)
事务隔离级别仅在不同类的多个方法间相互调用时生效。同一个类的多个方法相互调用,切面只会织入最上层的方法。
5、spring事务的实现原理
数据库事务+AOP,当添加了@Transaction注解后,事务的自动提交功能会关闭。
spring事务由数据库事务+AOP来实现,首先要生成具体的代理对象,然后根据AOP的整套流程来执行具体的操作逻辑,正常情况下aop要通过通知来完成核心功能,但事务不是通过通知来实现的,而是通过TransactionInterceptor来实现的,然后调用invoke实现具体的逻辑。
1、解析各方法上事务相关的属性,然后根据具体的属性来判断是否开启事务;
2、需要开启事务时,则获取数据库连接,关闭事务的自动提交,开启事务;
3、执行具体的sql逻辑;
4、若执行失败,通过completeTransactionAfterThrowing doRollBack来完成事务的回滚操作,实现时需先获取连接对象,通过连接对象回滚事务;
5、若执行成功,通过completeTransactionAfterReturning doCommit来完成事务的提交,,实现时需先获取连接对象,通过连接对象提交事务;
6、事务执行完毕后清除相关的事务信息,clenupTransactionInfo