1.编程式事务
这种需要自己手动编写事务代码的控制方式已经严重过时了,因为每个执行DML语句的操作都要编写一份这样的代码,相当的麻烦,Spring提供了一个抽象层:PlantformTransactionManager,事务管理器。封装了数据库事务几个方法,
commit、rollback、getTransaction。想在Spring平台使用事务,就必须提供一个
PlantformTransactionManager的子类,Spring有一个实现类:DataSourceTransactionManager。
2.Spring事务配置
Spring的事务控制是基于AOP编程思想上实现的,配置文件中需要的Schema:
有tx包的地方也要有aop包。
a) 基本配置步骤:
1.首先声明一个Datasource,创建事务管理器需要到这个实例。
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${url}" ></property> <!-- 添加里面的属性 -->
<property name="username" value="${userid}" ></property>
<property name="password" value="${password2}" ></property>
<property name="driverClassName" value="${driverClass}" ></property>
</bean>
2.声明一个Spring的事务管理器:
<!-- 事务管理器 不再使用jdbc的commit和rollback 必须由事务管理器提供 配置事物管理器必须要注入dataSource-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
3.定义通知
<!-- 定义事物里面的通知 通知的代码 spring已经实现 事务管理器如果是transactionManager命名 可以省略 transaction-manager="transactionManager"-->
<tx:advice id="myAdvise" transaction-manager="transactionManager">
<tx:attributes>
<!--tx:method的作用是拦截指定方法开头的 然后对他进行事物处理 -->
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="save*" />
<tx:method name="delete*"/>
<!--read-only="true" 意思是除了上面拦截的以外 其他的都不拦截-->
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
意义:通知的概念知道AOP编程的都知道,不多BB ,数据库事务的前置后置通知的代码Spring是 已经封装好了的,直接指定就OK了。transaction-manager默认值是transactionManager,如果在声明管理器Bean的时候id为transactionManager,那么在这里是 不需要手动指定的,若不是,则手动指定 transaction-manager无论是获取连接、关闭自动提交、等前置通知,还是异常回滚的异常通知、 业务代码 执行完后提交事务的后置通知,Spring都帮我们把相关的逻辑封装好了, 只需要专注自己的业务逻辑即可。
name:
用于指定需要事务支持的方法,update*指的是update开头的所有方法,以此类推。
propagation(传播级别):
REQUIRED:如果父方法没有事务就创建一个事务,如果有就使用当前事务。
REQUIRED_NEW:无论父方法有没有事务,都创建一个新的
SUPPORTS: 如果父方法没有事务则使用JDBC的事务(自动提交),否则使用父方法的事务
NOT_SUPPORTS:无论父方法有没有事务,都是用JDBC的事务(挂起父方法的事务)。
MANDATORY:如果方法没有运行在Spring事务中就抛出异常,必须在事务环境下运行
NEVER:父方法不能存在事务,有事务就抛出异常
4.切点关联
关联到上方定义的通知即可。
设置回滚事务属性:
Spring事务管理中异常回滚默认情况下只对RuntimeException有效,非运行时异常是不会回滚的。不过<tx:method>标签中有两个属性可以指定遇到哪种类型的异常时回滚数据:
rollback - for:指定会自动回滚的非运行时异常,IO异常、反射异常、SQL异常等等。
no - rollback - for:指定不会回滚的运行时异常,空指针、下标越界等等。
事务的回滚规则可以通过@Transactional 注解或者配置文件设置:
1.注解:通过rollbackFor 和 noRollbackFor 属性来定义。
这两个属性被声明为 Class[] 类型的, 因此可以为这两个属性指定多个异常类:
在 Spring 2.x 事务通知中, 可以在 <tx:method> 元素中指定回滚规则,如果有不止一种异常, 用逗号分隔:
超时和只读属性
由于事务可以在行和表上获得锁,因此长事务会占用资源,并对整体性能产生影响.,
如果一个事务只读取数据但不做修改,数据库引擎可以对这个事务进行优化:
超时事务属性: 事务在强制回滚之前可以保持多久,这样可以防止长期运行的事务占用资源
只读事务属性: 表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务
超时和只读属性可以在 @Transactional 注解中定义.超时属性以秒为单位来计算:
在 Spring 2.x 事务通知中,超时和只读属性可以在 <tx:method> 元素中进行指定: