一. 声明式事务
通过AOP实现,事务开启放在前置通知,事务提交放在成功返回的后置通知,事务回滚放在异常通知中。
1.XML方式配置
<!-- 配置声明式事务-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 事务管理最终需要connection对象完成 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
设置指定方法织入事务通知
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="methodName"/>
</tx:attributes>
</tx:advice>
<!-- 1. 设定哪个方法需要被声明式事务管理,使用AOP完成,通过切点定义需要进行声明式事务管理的方法 -->
<aop:config>
<aop:pointcut id="mypoint" expression="execution(* 包名.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"></aop:advisor>
</aop:config>
2.注解方式
@Transactional属性
1.readOnly:只能用在查询中。不会开启事务。
2.timeout:执行超过了设置的超时时间,回滚操作。(超时抛出异常)
3.rollbackFor:默认运行时异常和运行时异常的子类回滚。
4.noRollbackFor:遇到指定异常不回滚。
5.propagation:事务传播行为
1.同一个类中的方法相互调用,使用同一个事务。
2.调用不同类中的方法,事务存在传播行为。
属性值:
1.Propagation.REQUIRED(默认):当前有事务,使用当前事务。没有事务,开启新的事物。
2.Propagation.NEVER:必须在非事务状态下执行。没有事务,正常运行。有事务,抛出异常。
3.Propagation.NESTED:必须在事务状态下执行。没有事务,创建事务。有事务,创建嵌套事务。
4.Propagation.REQUIRES_NEW:没有事务,创建事务。有事务,挂起当前事务,创建新的事务。最后统一操作。
5.SUPPORTS:没有事务,非事务执行。有事务,使用当前事务。
6.Propagation.NOT_SUPPORTED:非事务下执行。有事务,挂起事务,以非事务执行,执行后,恢复挂起的事务。
7.propagation = Propagation.MANDATORY:事务下执行。没有事务,抛出异常。
6.isolation:事务隔离级别
脏读:一个事务读取到了其他事务未提交的数据。
不可重复读:一个事务多次读取,读取的数据不一致,其他事务进行了修改的操作。
幻读:一个事务多次读取,读取的数据不一致,其他事务进行了添加的操作。
1.Isolation.READ_UNCOMMITTED:读未提交(出现,脏读,不可重复读,幻读)。
2.Isolation.READ_COMMITTED:读已提交(出现,不可重复读,幻读)。
3.Isolation.REPEATABLE_READ:可重复读(解决常规的幻读)。
MVCC:版本控制工具。理解为快照读。
例如:修改全部数据会出现幻读。
4.Isolation.SERIALIZABLE:序列化(没有任何问题)
为表添加表锁,同一时刻只能一个事务操作。
注意:使用声明式事务时,不能使用try catch
二.获取属性文件中的值
--配置参数配置文件路径--
<context:property-placeholder location="classpath:db.properties"/>
@Value("${键名}")
作用:用来替换配置文件中的属性注入的。
使用:在属性上声明,值为${“键名”}
底层使用反射实现属性赋值
三.bean的生命周期
1.编写bean的定义信息(xml,注解)
2.通过BeanDefinitionReader 读取bean的定义信息
3.解析出bean的定义信息
4.可以通过BeanFactoryPostProcessor接口实现类,操作bean的定义信息
5.实例化bean对象
6.属性注入
7.可以使用相关的Aware接口,可以获取bean的相关信息,容器信息...
8.可以使用BeanPostProcessor接口中before方法操作对象
9.可以使用init-method调用自定义的初始化方法
<bean id="类名(首字母小写)" class="包名.类名" init-method="init">
10.可以使用BeanPostProcessor接口中after方法操作对象
11.存储到单例池(一级缓存中)
12.销毁
<bean id="类名(首字母小写)" class="包名.类名" destroy-method="destroy">