您的位置:首页 > 编程语言 > Java开发

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/>有关的设置

属性是否需要?默认值描述
name与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法。如:'get*'、'handle*'、'on*Event'等等。
propagationREQUIRED事务传播行为
isolationDEFAULT事务隔离级别
timeout-1事务超时的时间(以秒为单位)
read-onlyfalse事务是否只读?
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方法进行事务管理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: