Spring AOP 事务管理
2015-12-08 11:37
393 查看
首先需要配置一个 Bean 称之为事务管理器。有DataSourceTransactionManager、HibernateTransactionManager等。
然后用tx:advice标签配置事务。tx即是transaction的简写。定义事务属性:传播、隔离级别、读写、超时、异常。
最后用 aop 方式配置添加事务的切点。
name:方法名的匹配模式,通知根据该模式寻找匹配的方法。
propagation:设定事务定义所用的传播级别。
isolation:设置事务的隔离级别。
timeout:指定事务的超时(秒)。
read-only:该属性为true指示事务是只读的
no-rollback-for:以逗号分隔的异常类的列表,目标方法可以跑出这些异常而不会导致通知执行回滚
rollback-for:以逗号分隔的异常类的列表,当目标方法跑出这些异常时会导致通知执行回滚。默认情况下,该列表为空,因此不在no-rollback-for列表中的任何运行时异常都会导致回滚。
ISOLATION_READ_UNCOMMITTED 最低的隔离级别。事实上我们不应该隔离级别,因为在事务完成前,其他事务可以看到该事务所修改的数据。而在其他事务提交前,该事务也可以看到其他事务所做的修改。
ISOLATION_READ_COMMITTED 大多数数据库的默认级别。在事务完成前,其他事务无法看到该事务所修改的数据。遗憾的是,在该事务提交后,你就可以查看其他事务插入活更新的数据。这意味着在事务的不同点上,如果其他事务修改数据,你会看到不同的数据。
ISOLATION_REPEATABLE_READ 该隔离级别确保如果在事务中查询了某个数据集,你至少还能再次查询到相同的数据集,即使其他事务修改了所查询的数据。然而如果其他事务插入了新数据,你就可以查询到该新插入的数据。
ISOLATION_SERIALIZABLE 代价最大、可靠性最高的隔离级别,所有的事务都是俺顺序一个接一个的执行。
PROPAGATION_SUPPORTS 当前如果有事务,Spring就会使用该事务;否则不会开启一个新事务。
PROPAGATION_MANDATORY 当前如果有事务,Spring就会使用该事务;否则会抛出异常。
PROPAGATION_REQUIRES_NEW Spring总会开始一个新事务。如果当前有事务,则该事务挂起。
PROPAGATION_NOT_SUPPORTED Spring不会执行事务中的代码。代码总是在非事务环境下执行,如果当期有事务,则该事务挂起。
PROPAGATION_NEVER 即使当前有事务,Spring也会在飞事务环境下执行。如果当前有事务,则抛出异常。
PROPAGATION_NESTED 如果当前有事务,则在嵌套事务中执行。如果没有,那么执行情况与PROPAGATION_REQUIRED一样。
modifiers-pattern 表示public、protected等,省略则表示任意。
ret-type-pattern 表示返回值类型,不能省略,用 * 匹配任意。
declaring-type-pattern 表示包路径和类名称,省略则表示任意。
name-pattern 表示方法名称,不能省略,用 * 匹配任意。
param-pattern 表示参数,不能省略,用 .. 匹配任意,用 * 匹配一个参数。
throws-pattern 表示异常,省略则表示任意。
下面给出一些通用切入点表达式的例子。
execution(public * *(..)) 任意公共方法
execution(* set*(..)) 任何一个名字以“set”开始的方法
execution(* com.xyz.service.AccountService.*(..) AccountService接口定义的任意方法
execution(* com.xyz.service..(..)) 在service包中定义的任意方法
execution(* com.xyz.service...(..)) 在service包或其子包中定义的任意方法
然后用tx:advice标签配置事务。tx即是transaction的简写。定义事务属性:传播、隔离级别、读写、超时、异常。
最后用 aop 方式配置添加事务的切点。
<!-- 事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 事务 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="query*" read-only="true" /> <tx:method name="find*" read-only="true" /> </tx:attributes> </tx:advice> <!-- 使用事务的切点 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..service..*.*(..))"/> </aop:config>
<tx:method/>
标签的属性
name:方法名的匹配模式,通知根据该模式寻找匹配的方法。propagation:设定事务定义所用的传播级别。
isolation:设置事务的隔离级别。
timeout:指定事务的超时(秒)。
read-only:该属性为true指示事务是只读的
no-rollback-for:以逗号分隔的异常类的列表,目标方法可以跑出这些异常而不会导致通知执行回滚
rollback-for:以逗号分隔的异常类的列表,当目标方法跑出这些异常时会导致通知执行回滚。默认情况下,该列表为空,因此不在no-rollback-for列表中的任何运行时异常都会导致回滚。
isolation隔离级别
ISOLATION_DEFAULT 默认级别(对大多数数据库来说就是ISOLATION_READ_COMMITTED)ISOLATION_READ_UNCOMMITTED 最低的隔离级别。事实上我们不应该隔离级别,因为在事务完成前,其他事务可以看到该事务所修改的数据。而在其他事务提交前,该事务也可以看到其他事务所做的修改。
ISOLATION_READ_COMMITTED 大多数数据库的默认级别。在事务完成前,其他事务无法看到该事务所修改的数据。遗憾的是,在该事务提交后,你就可以查看其他事务插入活更新的数据。这意味着在事务的不同点上,如果其他事务修改数据,你会看到不同的数据。
ISOLATION_REPEATABLE_READ 该隔离级别确保如果在事务中查询了某个数据集,你至少还能再次查询到相同的数据集,即使其他事务修改了所查询的数据。然而如果其他事务插入了新数据,你就可以查询到该新插入的数据。
ISOLATION_SERIALIZABLE 代价最大、可靠性最高的隔离级别,所有的事务都是俺顺序一个接一个的执行。
propagation传播行为
PROPAGATION_REQUIRED 当前如果有事务,Spring就会使用该事务;否则会开始一个新事务。PROPAGATION_SUPPORTS 当前如果有事务,Spring就会使用该事务;否则不会开启一个新事务。
PROPAGATION_MANDATORY 当前如果有事务,Spring就会使用该事务;否则会抛出异常。
PROPAGATION_REQUIRES_NEW Spring总会开始一个新事务。如果当前有事务,则该事务挂起。
PROPAGATION_NOT_SUPPORTED Spring不会执行事务中的代码。代码总是在非事务环境下执行,如果当期有事务,则该事务挂起。
PROPAGATION_NEVER 即使当前有事务,Spring也会在飞事务环境下执行。如果当前有事务,则抛出异常。
PROPAGATION_NESTED 如果当前有事务,则在嵌套事务中执行。如果没有,那么执行情况与PROPAGATION_REQUIRED一样。
Spring AOP 执行表达式 execution 格式
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)modifiers-pattern 表示public、protected等,省略则表示任意。
ret-type-pattern 表示返回值类型,不能省略,用 * 匹配任意。
declaring-type-pattern 表示包路径和类名称,省略则表示任意。
name-pattern 表示方法名称,不能省略,用 * 匹配任意。
param-pattern 表示参数,不能省略,用 .. 匹配任意,用 * 匹配一个参数。
throws-pattern 表示异常,省略则表示任意。
下面给出一些通用切入点表达式的例子。
execution(public * *(..)) 任意公共方法
execution(* set*(..)) 任何一个名字以“set”开始的方法
execution(* com.xyz.service.AccountService.*(..) AccountService接口定义的任意方法
execution(* com.xyz.service..(..)) 在service包中定义的任意方法
execution(* com.xyz.service...(..)) 在service包或其子包中定义的任意方法
相关文章推荐
- java泛型程序设计——泛型类的静态上下文中类型变量无效+不能抛出或捕获泛型类的实例
- Java下载文件
- 【Struts2】(7)ModelDriven和类型转换器
- 关于解决spring 只能跳转到.jsp 不能跳转到.html的问题
- Java的native关键字
- 策略模式 java实现
- java线程中yield()和join()的区别
- Eclipse 常用快捷键
- JAVA虚拟机干货
- maven 把spring项目打包成可执行的文件
- java泛型程序设计——Varargs 警告+不能实例化类型变量
- 1003. 我要通过!(20) JAVA pattern
- java泛型类和泛型函数
- Java—字符串小结
- javaWeb中的文件上传下载
- 1002. 写出这个数 (20) JAVA
- JAVA中String及常用操作函数
- Java I/O— 梳理各种“流”
- 1001. 害死人不偿命的(3n+1)猜想 (15) java
- java 突击队注意事项:在路上