最近想搭个spring框架,可中间涉及到事务。因为数据层会用到ibatis或者hibernate 所以没有用最原始的jdbc来管理事务,网上找了下一般都用spring Aop来管理事务,配置挺方面的,以下是事务配置的几种方式,希望能帮到初学者,我也刚接触有好的建议提出来。
一 transactionTemplate; 来管理事务 。它主要是通过配置来实例化一个transactionTemplate对象。然后在需要用到事务的地方进行事务处理,配置稍简单
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-2.0.xsd"
default-autowire="byName">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8">
</property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
</bean>
<bean id="client"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"
value="classpath:sqlmapconfig.xml">
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="baseDao" class="com.dao.BaseDao">
<property name="sqlMapClient">
<ref bean="client"></ref>
</property>
</bean>
<bean id="myAction" class="com.action.MyAction" scope="prototype">
<property name="dao">
<ref bean="baseDao"></ref>
</property>
</bean>
</beans>
package com.action;
import java.util.List;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.dao.BaseDao;
import com.vo.Emp;
public class MyAction {
private Emp emp;
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public String insertEmp() {
transactionTemplate.execute(new TransactionCallback<Object>(){
public Object doInTransaction(TransactionStatus arg0) {
// TODO Auto-generated method stub
try{
dao.insert("emp.insert", emp);
Integer.parseInt("sdsdd");
}catch(Exception e){
System.out.println("taijiadjjdkljdklj");
arg0.setRollbackOnly();
}
return 0;
}
});
return "ok";
}
}
在添加时处理事务,抛出一个异常,结果添加数据回滚!验证成功
二 TransactionAspectSupport 得到当前的transaction来进行事务操作,操作简便,在catch处进行事务回滚.
代码如下:
<?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-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8">
</property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="client"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"
value="classpath:sqlmapconfig.xml">
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="baseDao" class="com.dao.BaseDao">
<property name="sqlMapClient">
<ref bean="client"></ref>
</property>
</bean>
<bean id="myAction" class="com.action.MyAction" scope="prototype">
<property name="dao">
<ref bean="baseDao"></ref>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="proxyTargetClass" value="true" />
<property name="beanNames">
<value>*Dao</value><!-- 给需要进行事务操作的serviec/dao BEAN来添加事务管理【可以使用通配符】-->
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
</beans>
dao操作方法如下
public void update(String tagName ,Object obj) throws MwException
{
logger.debug("修改");
try{
this.getSqlMapClientTemplate().update(tagName,obj);
float f=1/0;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//异常回滚操作
logger.debug("修改用户事务回滚了......");
}
}
三 tx:advice来配置事务,只不过有点小问题。只能对unchecked Exception进行回滚,对checked Exception 不能回滚
一下是配置,
<?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-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8">
</property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="client"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"
value="classpath:sqlmapconfig.xml">
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="baseDao" class="com.dao.BaseDao">
<property name="sqlMapClient">
<ref bean="client"></ref>
</property>
</bean>
<bean id="myAction" class="com.action.MyAction" scope="prototype">
<property name="dao">
<ref bean="baseDao"></ref>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" autowire="default">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(* com.dao..*.*(..))" id="almethod"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="almethod"/>
</aop:config>
</beans>
dao方法:
public void update(String tagName ,Object obj) throws MwException
{
logger.debug("修改");
try{
this.getSqlMapClientTemplate().update(tagName,obj);
float f=1/0;
} catch (Exception e) {
logger.debug("修改用户事务回滚了......");
// throw new MwException("EXCEPTION");
}
}
这种方法只能对RuntimeException或其之类进行回滚,对其他catch异常不进行回滚,所以要在catch里面抛出一个RuntimeException异常来进行回滚,可是这样我页面就报RuntimeException异常。显示错误了。哎,真不知道这种方式别人是怎么处理的,如果有大神知道,请告知一下,谢谢!