转载http://blog.csdn.net/kolkosky/article/details/2071242
Spring 实现ibatis事务回滚
这两天做一个网站需要在数据报错时自动对数据进行回滚,在此期间遇到一些问题,现做下笔记
这里使用spring-Aop代理机制来实现事务的回滚:
配置如下:
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>AppConfigServlet</servlet-name>
<servlet-class>com.test.ConfigServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
ApplicationContext.xml
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="businessTarget"
class="com.test.BusinessInterfaceImpl" />
<bean id="businessBean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="singleton">
<value>true</value>
</property>
<property name="proxyInterfaces">
<value>com.test.BusinessInterface</value>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
<value>businessTarget</value>
</list>
</property>
<property name="proxyTargetClass"><value>true</value></property>
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>gissys</value>
</property>
</bean>
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>
classpath:com/emaptech/persistence/SqlMapConfig.xml
</value>
</property>
<property name="dataSource" ref="dataSource"></property>
</bean>
Ibatis.xml
<insert id="testInsert" parameterClass="string">
insert into corebase.cc select 6,#value# from dual
</insert>
<insert id="testInsertWrong" parameterClass="string">
insert into corebase.cc select 6,#value#,7 from dual
</insert>
ConfigServlet.java
package com.test;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class ConfigServlet extends HttpServlet {
/**
* UID
*/
private static final long serialVersionUID = 5118794568550751611L;
public void init() throws ServletException {
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
BaseService.getInstance().init(ctx);
super.init();
}
}
BaseService.java
package com.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.ClassPathResource;
import com.ibatis.sqlmap.client.SqlMapClient;
public class BaseService implements ApplicationContextAware {
private static ApplicationContext ctx;
private static SqlMapClient sqlMapClient;
private static SqlMapClient sqlMapClientProxy;
private static BusinessInterface businessBean;
private static BaseService instance = new BaseService();
/**
* @return 返回 静态类
*/
public static BaseService getInstance(){
return instance;
}
/**
* @return 返回 初始化BaseService,存于内存
*/
public void init(ApplicationContext ctx) {
setApplicationContext(ctx);
setSqlMapClient(ctx);
setBusinessBean(ctx);
// setSqlMapClientProxy(ctx);
System.out.println(" INFO - 初始化baseservice成功");
}
public void setSqlMapClient(ApplicationContext ctx){
sqlMapClient = (SqlMapClient) ctx.getBean("sqlMapClient");
}
/**
* @return 返回 sqlMapClient。
*/
public SqlMapClient getInstanceSqlMapClient() {
return this.sqlMapClient;
}
/**
* 通过spring注入ApplicationContext
*
* @param ApplicationContext
* @return null
*/
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
ctx = arg0;
}
public Object getBean(String beanName) {
return ctx.getBean(beanName);
}
/**
* @return 返回 sqlMapClient。
*/
public SqlMapClient getSqlMapClient() {
return (SqlMapClient) ctx.getBean("sqlMapClient");
}
public void setSqlMapClientProxy(ApplicationContext ctx) {
sqlMapClientProxy= (SqlMapClient) ctx.getBean("sqlMapClientProxy");
}
public SqlMapClient getSqlMapClientProxy() {
return sqlMapClientProxy;
}
public static BusinessInterface getBusinessBean() {
return businessBean;
}
public static void setBusinessBean(ApplicationContext ctx) {
businessBean = (BusinessInterface) ctx.getBean("businessBean");
}
}
BusinessInterface.java
package com.test;
import java.sql.SQLException;
public interface BusinessInterface {
public void hello() throws SQLException;
}
BusinessInterfaceImpl.java
package com.test;
import java.sql.SQLException;
import com.ibatis.sqlmap.client.SqlMapClient;
public class BusinessInterfaceImpl implements BusinessInterface {
public void hello() throws SQLException {
System.out.println("hello Spring AOP.");
SqlMapClient sqlMapClient = BaseService.getInstance().getInstanceSqlMapClient();
sqlMapClient.startTransaction();
sqlMapClient.insert("testInsert","7");
System.out.println("1");
sqlMapClient.insert("testInsert","8");
System.out.println("2");
sqlMapClient.insert("testInsert","9");
System.out.println("3");
sqlMapClient.insert("testInsertWrong","10");
sqlMapClient.commitTransaction();
}
}
测试页面
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my JSP page. <br>
</body>
</html>