要成功都成功,要失败都失败
A给B转1000元钱,正常来说
A账户:-1000
B用户:+1000
如果不正常那么就可能会出现异常,比如说:
A账户:-1000
B用户:不加不减
就会出现减了这1000被蒸发掉了
那么这一篇 事务 就来举这个例子
一、数据库数据
二、Jsp页面
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<a href="transfer.action">点击转账</a>
</body>
</html>
三、domain层
package com.java.domain;
public class UpdateMoney {
private int id;
private int money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
四、mapper层
1、接口
package com.java.mapper;
import java.util.List;
import com.java.domain.UpdateMoney;
import com.java.domain.User;
public interface UserMapper {
//更新数据库money字段数据
void updateByMoney(UpdateMoney um);
}
2、xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace和mapper接口同名 -->
<mapper namespace="com.java.mapper.UserMapper">
<!-- id用接口中定义的方法的名字 -->
<update id="updateByMoney" parameterType="com.java.mapper.UserMapper">
update test003 set money=money+#{money} where id=#{id}
</update>
</mapper>
五、service接口层
package com.java.service;
import java.util.List;
import com.java.domain.User;
public interface UserService {
String transferAccounts();
}
六、service接口实现层
正常情况下的实现接口
package com.java.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.java.domain.UpdateMoney;
import com.java.domain.User;
import com.java.mapper.UserMapper;
import com.java.service.UserService;
@Service
public class UserServiceImpl implements UserService {
//自动装配,这个不需要导包,或者说已经导入过了;它是Spring自带的;默认直接按照类型进行装配,如果需要按照名字装配必须使用@Qualifier
@Autowired
private UserMapper userMapper;
@Override
public String transferAccounts() {
UpdateMoney u1 = new UpdateMoney();
u1.setId(2);
u1.setMoney(-1000);
UpdateMoney u2 = new UpdateMoney();
u2.setId(3);
u2.setMoney(1000);
userMapper.updateByMoney(u1);
userMapper.updateByMoney(u2);
return "转账成功!!!";
}
}
出现异常的实现接口(int a = 10/0;)
package com.java.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.java.domain.UpdateMoney;
import com.java.domain.User;
import com.java.mapper.UserMapper;
import com.java.service.UserService;
@Service
public class UserServiceImpl implements UserService {
//自动装配,这个不需要导包,或者说已经导入过了;它是Spring自带的;默认直接按照类型进行装配,如果需要按照名字装配必须使用@Qualifier
@Autowired
private UserMapper userMapper;
@Override
public String transferAccounts() {
UpdateMoney u1 = new UpdateMoney();
u1.setId(2);
u1.setMoney(-1000);
UpdateMoney u2 = new UpdateMoney();
u2.setId(3);
u2.setMoney(1000);
userMapper.updateByMoney(u1);
int a = 10/0;
userMapper.updateByMoney(u2);
return "转账成功!!!";
}
}
七、control层
package com.java.control;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import com.java.domain.User;
import com.java.service.impl.UserServiceImpl;
//交给spring管理
@Controller()
public class ControlDemo {
@Autowired
private UserServiceImpl userServiceImpl;
//映射路径
@RequestMapping("transfer")
public String transfer(Model model) {
String transferAccounts = userServiceImpl.transferAccounts();
return "success.jsp";
}
}
正常情况运行得出结果是这样的
那么不正常就是这样的
————————————————————————————————————————
怎样解决呢?很简单,我这里使用的注解形式,还有其它方式,可百度
配置applicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<!-- 配置注解扫描范围 -->
<context:component-scan base-package="com.java.service.impl,com.java.test" />
<!-- 读取database.properties文件 -->
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 指定properties文件所在路径 -->
<property name="location" value="classpath:database.properties"></property>
</bean>
<!-- Dbcp配置数据源 -->
<!-- <context:property-placeholder location="classpath:database.properties"/> -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 配置事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 事务注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 配置扫描保存sql语句的局部xml文件 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 指定局部xml文件的位置 -->
<property name="mapperLocations" value="classpath*:com/java/mapper/*.xml"></property>
</bean>
<!-- 扫描mapper接口类,并且将接口类与xml文件关联 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定mapper接口类存放的位置 -->
<property name="basePackage" value="com.java.mapper"></property>
</bean>
</beans>
然后需要在方法上面开启事务@Transactional()
最后结果就是要成功都成功,要失败都失败。