Spring in action读书笔记-事务管理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring in action读书笔记-事务管理相关的知识,希望对你有一定的参考价值。
在软件开发领域,全有全无的操作被称为事务
事务的四个特性(ACID):
- 原子性(Atomtic):事务是由一个或多个活动所组成的一个工作单元,要么全部发生,要么全部不发生。
- 一致性(Consistent):一旦事务完成,系统应确保它所建的业务处于一致的状态。
- 隔离性(Isolated):事务允许多个用户操作同样的数据,但不能相互影响。
- 持久性(Durable):事务的结果应该存到数据库或者其他形式的持久化存储中。
spring对事务管理的支持:
- 编码式:允许用户在代码中精确定义事务的边界
- 声明式:有助于用户将操作与事务规则进行解耦
spring的事务管理器:
事务管理器(org.framework.*) |
使用场景 |
|
|
Jdbc.datasource.DataSourceTransactionManager |
用于Spring对JDBC抽象的支持,也可用于使用ibatis进行持久化场景 |
|
|
|
|
|
|
|
|
|
|
1 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 2 <property name="dataSource" ref="datasource" /> 3 </bean>
声明事务的三种方式:
- 使用SpringAOP和TransactionProxyFactoryBean的代理Bean来实现
- Spring的tx命名空间
- @Transactional注解
事务属性描述了事务策略如何应用到方法上,具体属性如下:
1. 传播行为:定义了客户端与被调用方法之间的事务边界。(P155,表6.2)
传播行为 |
含义 |
PROPAGATION_MANADATORY |
表示该方法必须在事务中运行,如果当前事务不存在,在会抛出异常 |
PROPAGATION_NESTED |
如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为和 |
PROPAGATION_NEVER |
表示当前方法不应该运行在事务上下文中,如果当前正有一个事务在运行,则会抛出异常 |
PROPAGATION_NOT_SUPPORTED |
表示该方法不应该运行在事务中,如果存在当前事务,在方法运行期间,当前事务将被挂起。 |
PROPAGATION_REQUIRED |
表示当前方法必须运行在事务中,如果当前事务存在方法将会在该事务中运行,否则,会启动一个新的事务。 |
PROPAGATION_REQUIRES_NEW |
表示当前方法必须运行在它自己的事务中,一个新的事务将被启动。如果存在当前事务,该方法执行期间,当前事务会被挂起。 |
PROPAGATION_SUPPORTS |
表示当前方法不需要事务上下文,但如果存在当前事务的话,那么该方法会在这个事务中运行,但并不要求必须在事务中运行。 |
2. 隔离级别:定义了一个事务可能受其他并发事务影响的程度。
事务并发可能导致的问题:
- 脏读:事务T1读取了事务T2改些后还未提交的数据,T1读取的数据是无效的。
- 不可重复读:事务T1在查询时,事务T2更新了数据,事务T1再查询时与第一次查询数据不一致了。
- 幻读:事务T1读取了事务T2插入的一些数据
一般情况下事务是完全隔离的,但完全隔离影响性能,因此需要事务隔离级别来增加事务的灵活性。
隔离级别 |
含义 |
ISOLATION_DEFAULT |
使用后端数据库默认的隔离级别 |
ISOLATION_READ_UNCOMMITTED |
允许读取尚未提交的数据变更,可能会导致脏读,幻读或不可重复读 |
ISOLATION_READ_COMMITTED |
允许读取并发事务已经提交的数据,可以阻止脏读,但幻读和不可重复读仍可能发生 |
ISOLATION_REPEATABLE_READ |
对同一字段的多次读取结果是一致的,除非数据是被本事务自己所修改。可以阻止脏读和不可重复读写,但幻读仍可能发生 |
ISOLATION_SERIALIZABLE |
完全服从ACID的隔离级别,完全锁定相关事务,性能较低 |
3. 只读:数据库可以利用事务的只读特性来进行一些特定的优化
4. 事务超时:事务可能涉及对后端数据库的锁定,事务时间过长会占用数据库资源,需指定超时时间自动回滚。
5. 回滚规则:默认情况下事务只有在遇到运行时异常才会回滚,你也可以设置在遇到检查型异常时也回滚,或者运行时异常不回滚。
在XML中定义事务
- 早期:声明事务需要装配一个名为TransactionProxyFactoryBean的特殊bean
- 现在:使用tx命名空间会将其添加到SpringXML配置文件中(P158),一些声明式事务配置元素依赖于部分spring的AOP配置元素,aop命名空间也应该包括在内。
1 <tx:advice id = "txAdvice"> 2 3 <tx:attributes> 4 5 <tx:method name="save*" propagation = "REQUIRED" /> 6 7 <tx:method name ="*" propagation="SUPPORTS" read-only = "true"/> 8 9 </tx:attributes> 10 11 </tx:advice>
<tx:method> 有多个属性来帮助定义方法的事务策略:
隔离级别 |
含义 |
isolation |
指定事务的隔离级别 |
propagation |
定义事务的传播规则 |
read-only |
指定事务为只读 |
回滚规则: rollbak-for no-rollback-for |
指定事务对于那些检查型异常应当回滚而不提交 指定事务对于那些异常应当继续运行而不回滚 |
timeout |
对于长时间运行的事务定义超时时间 |
定义注解驱动的事务
使用注解的方式只需配置一行XML:<tx : annotation-driven />,它会告诉Spring检查上下文中所有使用@Transactional注解的Bean,自动为它们添加事务通知,通知的属性是通过@Transactional注解的参数来定义的:
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class) public void addAndUpdateOrders(List<InvoiceOrderApi> invoiceOrderApis, List<InvoiceOrder> invoiceOrders, InvoiceApply apply){ ... }
也可以配置指定特定的事务管理器:<tx : annotation-driven transaction-manager = "txManager"/>
以上是关于Spring in action读书笔记-事务管理的主要内容,如果未能解决你的问题,请参考以下文章