Spring的事务处理机制及JAVA异常
2016-02-23 18:56
477 查看
在java中,异常分为两种,运行时异常(也就是uncheckException)和已检查异常checkException,运行时异常包括平常遇到的各种异常,如空指针异常,数据格式异常等一系列异常,这种异常是可以不捕获的,可通过throws抛出异常,交给别的代码或者JAVA虚拟机来完成。但是checkException是必须要处理的,也就是不能抛出,必须通过try-catch来完成,不处理的话是不能进行编译的。但是checkException不是一个具体的异常类型,它只是一个概念。所以你判断一个异常是已检查异常还是未检查异常,只需要通过抛出这个异常就可以知道了。
Spring的事务回滚机制对于运行时异常会直接回滚,对于checkExceptom则需要通过rollbackfor属性让其进行回滚。Spring事务机制一般分为4步:第一步声明事务名称,一般默认为transactionManager。第二部利用tx配置书屋的传播特性,第三部利用aop设置一个pointCut第四步利用aop:advisor方式,把第二步和第三步连接起来
<?xml
version="1.0"
encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"
>
<bean
id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
abstract="false"
lazy-init="default"
autowire="default"
dependency-check="default">
<
property
name="sessionFactory">
<ref
bean="sessionFactory"
/>
</property>
</bean>
<
tx:advice
id="txAdvice"
transaction-manager="transactionManager">
<
tx:attributes>
<tx:method
name="add*"
propagation="REQUIRED"
/>
<tx:method
name="delete*"
propagation="REQUIRED"
/>
<tx:method
name="update*"
propagation="REQUIRED"
/>
<tx:method
name="add*"
propagation="REQUIRED"
/>
<!--<tx:methodname="*"propagation="true"/>-->
</tx:attributes>
</tx:advice>
<
aop:config>
<
aop:pointcut
id="allManagerMethod"
expression="execution(*com.service.*.*(..))"
/>
<
aop:advisor
advice-ref="txAdvice"
pointcut-ref="allManagerMethod"
/>
</aop:config>
</beans>
Eclipse不能识别<tx:advice/>标签
在开发Spring的过程中,有时会出现Eclipse不能识别<tx:advice/>标签。
提示出现以下错误:
Theprefix"tx"forelement"tx:advice"isnotbound
这个错误的原因很简单是:
我们在定义申明AOP的时候。。没有加载schema。
具体表现如下:
Xml代码
<beans>
<tx:advice
id="txAdvice"
transaction-manager="transactionManager">
<
tx:attributes>
<
tx:method
name="get*"
read-only="true"/>
<
tx:method
name="*"
propagation="REQUIRES_NEW"
rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!--aop代理设置-->
<aop:config
proxy-target-class="true">
....
</aop:config>
</beans>
这时会抛出异常不认<TX>标签。。起先还以为是没有加载JAR包呢。。
后来读AOP文档才发现<beans>中要加入“xmlns:aop”的命名申明,并在“xsi:schemaLocation”中指定aop配置的schema的地址
配置文件如下:
Xml代码
<?xml
version="1.0"
encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
这些才是最关键的地方。。后面的配置不变。。。。
Spring使用<tx:advice>和<aop:config>用来配置事务,具体如何配置你可以参考Spring文档。
综上:包com.evan.crm.service下的任意class的具有任意返回值类型、任意数目参数和任意名称的方法
<tx:advice/>有关的设置
这一节里将描述通过<tx:advice/>标签来指定不同的事务性设置。默认的<tx:advice/>设置如下:
事务传播设置是REQUIRED
隔离级别是DEFAULT
事务是读/写
事务超时默认是依赖于事务系统的,或者事务超时没有被支持。
任何RuntimeException将触发事务回滚,但是任何checkedException将不触发事务回滚
这些默认的设置当然也是可以被改变的。<tx:advice/>和<tx:attributes/>标签里的<tx:method/>各种属性设置总结如下:
表9.1.<tx:method/>有关的设置
这是另外一种配置如下(不推荐):
然后,你需要配置的是对那个类的进行拦截器事务管理,就就需要设置这个接口的parent属性为baseTransactionProxy,target是该接口的实现类。如下:
上面的accountBiz是一个接口,它的实现类的id是accountBizImpl。然后你在Struts或SpringMVC中注入accountBiz这个接口即可使用里面的方法了。
糟糕的是,你需要为所有需要事务管理的类或接口都要进行这个配置!也许你可以配置一个BaseBiz的parent是baseTransactionProxy,然后所有要进行
事务管理的接口或类,继承或实现BaseBiz这个接口。不妨可以尝试一番!
当然你也可以用最常见的aop方法进行事务管理。
Spring的事务回滚机制对于运行时异常会直接回滚,对于checkExceptom则需要通过rollbackfor属性让其进行回滚。Spring事务机制一般分为4步:第一步声明事务名称,一般默认为transactionManager。第二部利用tx配置书屋的传播特性,第三部利用aop设置一个pointCut第四步利用aop:advisor方式,把第二步和第三步连接起来
<?xml
version="1.0"
encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
>
<bean
id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
abstract="false"
lazy-init="default"
autowire="default"
dependency-check="default">
<
property
name="sessionFactory">
<ref
bean="sessionFactory"
/>
</property>
</bean>
<
tx:advice
id="txAdvice"
transaction-manager="transactionManager">
<
tx:attributes>
<tx:method
name="add*"
propagation="REQUIRED"
/>
<tx:method
name="delete*"
propagation="REQUIRED"
/>
<tx:method
name="update*"
propagation="REQUIRED"
/>
<tx:method
name="add*"
propagation="REQUIRED"
/>
<!--<tx:methodname="*"propagation="true"/>-->
</tx:attributes>
</tx:advice>
<
aop:config>
<
aop:pointcut
id="allManagerMethod"
expression="execution(*com.service.*.*(..))"
/>
<
aop:advisor
advice-ref="txAdvice"
pointcut-ref="allManagerMethod"
/>
</aop:config>
</beans>
Eclipse不能识别<tx:advice/>标签
在开发Spring的过程中,有时会出现Eclipse不能识别<tx:advice/>标签。
提示出现以下错误:
Theprefix"tx"forelement"tx:advice"isnotbound
这个错误的原因很简单是:
我们在定义申明AOP的时候。。没有加载schema。
具体表现如下:
Xml代码
<beans>
<tx:advice
id="txAdvice"
transaction-manager="transactionManager">
<
tx:attributes>
<
tx:method
name="get*"
read-only="true"/>
<
tx:method
name="*"
propagation="REQUIRES_NEW"
rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!--aop代理设置-->
<aop:config
proxy-target-class="true">
....
</aop:config>
</beans>
这时会抛出异常不认<TX>标签。。起先还以为是没有加载JAR包呢。。
后来读AOP文档才发现<beans>中要加入“xmlns:aop”的命名申明,并在“xsi:schemaLocation”中指定aop配置的schema的地址
配置文件如下:
Xml代码
<?xml
version="1.0"
encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
这些才是最关键的地方。。后面的配置不变。。。。
Spring使用<tx:advice>和<aop:config>用来配置事务,具体如何配置你可以参考Spring文档。
综上:包com.evan.crm.service下的任意class的具有任意返回值类型、任意数目参数和任意名称的方法
<tx:advice/>有关的设置
这一节里将描述通过<tx:advice/>标签来指定不同的事务性设置。默认的<tx:advice/>设置如下:
事务传播设置是REQUIRED
隔离级别是DEFAULT
事务是读/写
事务超时默认是依赖于事务系统的,或者事务超时没有被支持。
任何RuntimeException将触发事务回滚,但是任何checkedException将不触发事务回滚
这些默认的设置当然也是可以被改变的。<tx:advice/>和<tx:attributes/>标签里的<tx:method/>各种属性设置总结如下:
表9.1.<tx:method/>有关的设置
属性 | 是否需要? | 默认值 | 描述 |
name | 是 | 与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法。如:'get*'、'handle*'、'on*Event'等等。 | |
propagation | 不 | REQUIRED | 事务传播行为 |
isolation | 不 | DEFAULT | 事务隔离级别 |
timeout | 不 | -1 | 事务超时的时间(以秒为单位) |
read-only | 不 | false | 事务是否只读? |
rollback-for | 不 | 将被触发进行回滚的Exception(s);以逗号分开。如:'com.foo.MyBusinessException,ServletException' | |
no-rollback-for | 不 | 不被触发进行回滚的Exception(s);以逗号分开。如:'com.foo.MyBusinessException |
<!--配置事务管理器,注意这里的dataSource和SqlSessionFactoryBean的dataSource要一致,不然事务就没有作用了-->
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<!--配置事务的传播特性-->
<beanid="baseTransactionProxy"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"abstract="true">
<propertyname="transactionManager"ref="transactionManager"/>
<propertyname="transactionAttributes">
<props>
<propkey="add*">PROPAGATION_REQUIRED</prop>
<propkey="edit*">PROPAGATION_REQUIRED</prop>
<propkey="remove*">PROPAGATION_REQUIRED</prop>
<propkey="insert*">PROPAGATION_REQUIRED</prop>
<propkey="update*">PROPAGATION_REQUIRED</prop>
<propkey="del*">PROPAGATION_REQUIRED</prop>
<propkey="*">readOnly</prop>
</props>
</property>
</bean>
然后,你需要配置的是对那个类的进行拦截器事务管理,就就需要设置这个接口的parent属性为baseTransactionProxy,target是该接口的实现类。如下:
<!--为AccountBiz接口配置事务拦截器,baseTransactionProxy是事务拦截器,在Controller中获取这个对象-->
<beanid="accountBiz"parent="baseTransactionProxy">
<!--设置target,也就是AccountBiz的实现类-->
<propertyname="target"ref="accountBizImpl"/>
</bean>
上面的accountBiz是一个接口,它的实现类的id是accountBizImpl。然后你在Struts或SpringMVC中注入accountBiz这个接口即可使用里面的方法了。
糟糕的是,你需要为所有需要事务管理的类或接口都要进行这个配置!也许你可以配置一个BaseBiz的parent是baseTransactionProxy,然后所有要进行
事务管理的接口或类,继承或实现BaseBiz这个接口。不妨可以尝试一番!
当然你也可以用最常见的aop方法进行事务管理。
相关文章推荐
- Java 调用Dll
- Spring的AOP配置
- java中== equals 和comparTo的区别
- 关于context:component-scan扫描spring注解标记的用法
- 查看java进程的所有信息
- JAVA简易WEB服务器(二)
- Vin验证工具类
- maven工程出现java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
- JAVA运行时异常及常见的5中RuntimeExecption
- javaEE 后台框架 SpringMVC Mybatis Shiro druid
- Java中内存分配
- HDU1000A + B Problem(入门题,c,Java)
- java与C#的简单比较
- Spring加载配置文件
- Java回调机制与OOP思想
- org.springframework.web.context.ContextLoaderListener找不到的解决方法
- struts向jsp页面传值
- Eclipse 搭建Struts2
- java动态控制线程的启动和停止
- 基于Spring + Spring MVC + Mybatis + shiro 高性能web构建