一、Spring Transaction 简介:在复合型的数据库数据操作过程中,我们所预想的操作是数据一次性执行成功,当然这只是理想状态,常常由于各种原因导致复合操作执行到一半时就遇到各种异常(SQL Exception ,NumberFormat等)执行不下去,导致一堆脏乱数据。为了避免此类事件少发生,我们引入的数据的事务管理机制。这里我需要强调的是有了事务不一定保证数据的正确性,事务的回滚是有一些物理条件的(不能断电诸如此类),除此之外,这些的条件都是建立在程序正常的情况下。
二、关于Spring 事务,我们应该知道的知识点
1、 在了解Spring 事务之前我们首先需要了解Spring AOP,Spring 事务是建立在AOP的基础之上的,就像Spring Context建立在Spring Core之上,Ioc控制反转建立在依赖注入(DenpendyI)之上.至于AOP的实现无论是Cglib或者jdk我在这里就不一一叙述了。
2、事务的四种特性:
原子性:只有两种结果要么都成功,要没都失败(复合操作可能有多条数据库语句,没有超时这种)
一致性:种瓜得瓜,种豆得豆
持久性:事务一旦提交了,就永久在数据库中
隔离性:在数据库的并发操作中,会为每个用户提供一个事务,只有等其他的事务完成后才能进行自己的事务。像一个锁一样,永远最多只允许一个获得锁。
<!-- 配置事务通知属性 -->
<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"/>
<!-- 这句话的意思就是说,不要进行commit操作,不要进行rollback操作 -->
<tx:method name="query*" read-only="true"/>
</tx:attributes>
</tx:advice>
3、Spring中七种Propagation类的事务属性详解:
REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
4.
属性名 | 类型 | 说明 |
propagation | 枚举org.springframework.transaction.annotation.Propagation的值 | 事务传播行为 |
isolation | 枚举org.springframework.transaction.annotation.Isolation的值 | 事务隔离级别 |
readOnly | boolean | 事务读写性 |
三、事务代码的实现
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>
<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"/>
<!-- 这句话的意思就是说,不要进行commit操作,不要进行rollback操作 -->
<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.gupaoedu..*.service..*Service.*(..))" />
</aop:aspect>
</aop:config>
</beans>