准备
在说事务之前先想一个问题:
基于这个问题,可以考虑几个方面。
- 配置的定义逻辑。(事务有哪些重要的原则)
- 配置的实现。(怎么针对注解实现事务的控制)
- Spring 如何保证事务的成功。(比如MySql,Oracle不同的方式有自身不同的实现)
实现方式
事务的基本特性。
实现原理
Spring事务的实现其实是基于数据库对事务的实现,如果没有数据库的支持,Spring是无法提供事务功能的,可以理解为Spring是对数据库事务操作的封装。
- 创建数据库连接。
- 打开事务开关。
- 执行CRUD操作。
- 提交、回滚事务。
- 关闭连接。
Spring帮我们做的其实就是2和4。
关于配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务通知属性 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
<tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
<tx:method name="login" propagation="NOT_SUPPORTED"/>
<tx:method name="query*" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
<aop:aspect ref="dataSource">
<aop:pointcut id="transactionPointcut" expression="execution(public * com.*..*.service..*Service.*(..))" />
</aop:aspect>
</aop:config>
通过上述配置不难发现,Spring的事务是通过AOP代理的方式来实现。将Service包中的所有类生成代理对象,在代理对象被调用方法时,根据transactionManager的定义,来对需要提供事务的方法进行管理。