手动实现IOC与事务控制基于JDBC
sql
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`name` varchar(50) NOT NULL COMMENT ' 姓名',
`cardNo` varchar(50) NOT NULL COMMENT '卡号',
`money` int(11) NOT NULL COMMENT '金额'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES ('张三', '123456', '10000');
INSERT INTO `account` VALUES ('李四', '456789', '10000');
新建项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>stage01-spring</artifactId>
<groupId>com.liu</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-classroom</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>9099</port>
<path>/</path>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="false">
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Servlet
package com.liu.spring.servlet;
import com.alibaba.fastjson.JSON;
import com.liu.spring.factory.BeanFactory;
import com.liu.spring.result.Result;
import com.liu.spring.service.TransferService;
import com.liu.spring.service.impl.TransferServcieImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
/**
* @Description
* @ClassName TransferServlet
* @Author 刘楠
* @date 2020.06.24
*/
@WebServlet(name = "transferServlet",urlPatterns = "/transferServlet")
public class TransferServlet extends HttpServlet {
/**
* http mine,json类型
*/
public static final String MIME_TYPE_JSON = "application/json";
/**
* http mine,json类型指定utf-8编码
*/
public final static String MIME_TYPE_JSON_UTF8 = MIME_TYPE_JSON + ";charset=UTF-8";
//1.实例化TransferService
private TransferService transferService = new TransferServcieImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的字体编码
req.setCharacterEncoding("UTF-8");
String fromCardNo=req.getParameter("fromCardNo");
String toCardNo=req.getParameter("toCardNo");
String moneyValue = req.getParameter("money");
Integer money = Integer.valueOf(moneyValue);
//默认就是200
Result result = new Result();
try {
transferService.transfer(fromCardNo, toCardNo,money);
} catch (Exception e) {
e.printStackTrace();
result.setResult(Result.ResultEnum.SERVER_ERROR);
}
//设置响应字符编码
resp.setContentType(MIME_TYPE_JSON_UTF8);
resp.getWriter().println(JSON.toJSON(result));
}
}
##### Result
```java
/**
* @Description
* @ClassName Result
* @Author 刘楠
* @date 2020.06.24
*/
public class Result<T> implements Serializable {
private static final long serialVersionUID = -645547982453859521L;
private Integer status;
private String message;
private T data;
public Result() {
this(ResultEnum.SUCCESS);
}
public Result(ResultEnum result) {
setResult(result.getStatus(), result.getMessage());
}
public void setResult(ResultEnum result) {
status = result.getStatus();
message = result.getMessage();
}
public void setResult(int status, String message) {
this.status = status;
this.message = message;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return new StringJoiner(", ", Result.class.getSimpleName() + "[", "]")
.add("status=" + status)
.add("message='" + message + "'")
.add("data=" + data)
.toString();
}
public enum ResultEnum {
SUCCESS(200),
PARAM_ERROR(400),
NO_AUTH(401),
FORBIDDEN(403),
SERVER_ERROR(500),
FAILED(-1);
private int status;
private final static String[] initMsgs = { "执行成功","提交的数据错误","身份验证失败","无权限访问","执行错误","执行失败" };
private ResultEnum(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
/**
* 返回结果描述.
*
* @return 结果描述String
*/
public String getMessage() {
switch (status) {
case 200:
return initMsgs[0];
case 400:
return initMsgs[1];
case 401:
return initMsgs[2];
case 403:
return initMsgs[3];
case 500:
return initMsgs[4];
case -1:
return initMsgs[5];
default:
break;
}
return null;
}
}
}
service
public interface TransferService {
boolean transfer(String fromAccount, String toAccount, Integer money) throws SQLException, Exception;
}
service 实体类
package com.liu.spring.service.impl;
import com.liu.spring.dao.AccountDao;
import com.liu.spring.dao.impl.AccountDaoImpl;
import com.liu.spring.entity.Account;
import com.liu.spring.factory.BeanFactory;
import com.liu.spring.service.TransferService;
import com.liu.spring.transaction.TransactionManager;
import com.liu.spring.util.ConnectionUtils;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @Description
* @ClassName TransferServcieImpl
* @Author 刘楠
* @date 2020.06.23
*/
public class TransferServcieImpl implements TransferService {
private AccountDao accountDao = new AccountDaoImpl();
@Override
public boolean transfer(String fromAccount, String toAccount, Integer money) throws Exception {
System.out.println("=====开始转账==== ");
Account fAccount = accountDao.queryByCardNo(fromAccount);
Account tAccount = accountDao.queryByCardNo(toAccount);
fAccount.setMoney(fAccount.getMoney()-money);
tAccount.setMoney(tAccount.getMoney()+money);
accountDao.updateAccountByCardno(fAccount);
//int i=1/0; 异常用于测试 事务
accountDao.updateAccountByCardno(tAccount);
return true;
}
}
dao
public interface AccountDao {
/**
* 根据卡号查询
* @param cardNo
* @return
*/
Account queryByCardNo(String cardNo) throws SQLException;
int updateAccountByCardno(Account fAccount) throws SQLException;
}
dao实现类
package com.liu.spring.dao.impl;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.liu.spring.dao.AccountDao;
import com.liu.spring.entity.Account;
import com.liu.spring.util.ConnectionUtils;
import com.liu.spring.util.DruidUtils;
import javax.swing.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Description
* @ClassName AccountDaoImpl
* @Author 刘楠
* @date 2020.06.23
*/
public class AccountDaoImpl implements AccountDao {
@Override
public Account queryByCardNo(String cardNo) throws SQLException {
//从连接池获取连接
Connection connection = DruidUtils.getInstance().getConnection();
System.out.println("queryByCardNo connection "+connection.toString());
String sql = "select name ,cardNo ,money from account where cardNo=?";
//预编译SQL
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//填充参数
preparedStatement.setString(1, cardNo);
//执行查询
ResultSet resultSet = preparedStatement.executeQuery();
Account account = null;
while (resultSet.next()) {
account = new Account();
account.setMoney(resultSet.getInt("money"));
account.setCardNo(resultSet.getString("cardNo"));
account.setName(resultSet.getString("name"));
}
preparedStatement.close();
connection.close();
return account;
}
@Override
public int updateAccountByCardno(Account fAccount) throws SQLException {
Connection connection = DruidUtils.getInstance().getConnection();
System.out.println("updateAccountByCardno connection "+connection.toString());
String sql = "update account set money =? where cardNo=? ";
//预编译SQL
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置参数
preparedStatement.setInt(1, fAccount.getMoney());
preparedStatement.setString(2, fAccount.getCardNo());
//执行更新
int update = preparedStatement.executeUpdate();
preparedStatement.close();
connection.close();
return update;
}
}
实体类
public class Account implements Serializable {
private static final long serialVersionUID = -6836411742270629093L;
/**
* 帐户名称
*/
private String name;
/**
* 卡号
*/
private String cardNo;
/**
* 金额,余额
*/
private Integer money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
}
工具类
DruidUtils
public class DruidUtils {
private DruidUtils(){
}
private static DruidDataSource druidDataSource = new DruidDataSource();
static {
druidDataSource.setUrl("jdbc:mysql://127.0.0.1/bank?characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false");
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
}
public static DruidDataSource getInstance(){
return druidDataSource;
}
public static void main(String[] args) throws SQLException {
System.out.println(DruidUtils.getInstance().getConnection().toString());
}
}
使用tomcat7插件启动
测试 postman
正常执行没有问题
数据库也正常,
打开异常代码-重启项目
再次发送同样的请求
看数据库
第一个记录扣了钱,但第二记录并没有增加,钱不见了,因为没有事务控制
现在的问题
- Servlet中使用了new 关键字创建Service–代码耦合
- Service中也使用的new 创建dao—代码耦合
- 没有事务事务
一共2个大问题
代码代码耦合
* 使用工厂来创建对象,不使用new
没有事务
- 在servcie中的select,update方法每次都会创建一个新的连接,这样不是一个Connection,
- 同时每次执行完都把连接关闭了,再次又要重新获取新连接 肯定不是一个事务的见下方代码
* 事务控制JDBC默认是在dao层Connection对象的,控制在Service层中,解决就是把事务控制放在Service中
解决第一个问题-代码耦合
使用工厂来解决
使用配置文件的方式来声明bean
beans.xml
<beans>
<!--id标识 class 类的全限定类名-->
<bean id="transferService" class="com.liu.spring.service.impl.TransferServcieImpl">
<property name="AccountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="com.liu.spring.dao.impl.AccountDaoImpl">
</bean>
</beans>
只是名称和spring一样,没有任何关系
1.创建工厂来解析XML,
2.把对象实例保存
3. 提供接口获取对象
package com.liu.spring.factory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Description 使用反射创建对象
* @ClassName BeanFactory
* @Author 刘楠
* @date 2020.06.24
*/
public class BeanFactory {
/**
* 1.解析xml,将bean保存
* 2.提供获取对象的接口
*/
/**
* 保存对象
*/
private static Map<String, Object> beansMap = new ConcurrentHashMap<>();
private static String beansXml="beans.xml";
static {
//解析xml 保存在map中
//1.加载xml
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream(beansXml);
try {
Document document = new SAXReader().read(in);
//获取根据节点
Element rootElement = document.getRootElement();
//获取所有bean的标签
List<Element> beanList = rootElement.selectNodes("//bean");
for (Element element : beanList) {
/**
* 获取每个元素的id、class属性
*/
String id = element.attributeValue("id");
String clazz = element.attributeValue("class");
/**
* 通过反射创建对象
*/
Class<?> cla = Class.forName(clazz);
//实例化之后的对象
Object instance = cla.newInstance();
/**
* 放入map中
*/
beansMap.put(id, instance);
}
//实例化后,维护对象的依赖关系
List<Element> propertyList = rootElement.selectNodes("//property");
//解析property获取父元素
for (Element element : propertyList) {
String name = element.attributeValue("name");
String ref = element.attributeValue("ref");
//找到当前需要被处理依赖关系的Bean
Element parent = element.getParent();
//调用父元素的反射功能
String parantId = parent.attributeValue("id");
Object parantObject = beansMap.get(parantId);
Method[] methods = parantObject.getClass().getMethods();
for (Method method : methods) {
String methodName = method.getName();
//这个方法是要要赋值的方法
if(methodName.equalsIgnoreCase("set"+name)){
method.invoke(parantObject, beansMap.get(ref));
}
}
//重新放入容器
beansMap.put(parantId, parantObject);
}
} catch (DocumentException | ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* 根据id获取对象
* @param id
* @return
*/
public static Object getBean(String id){
Object o = beansMap.get(id);
return o;
}
}
修改servlet 与service
TransferServlet
@WebServlet(name = "transferServlet",urlPatterns = "/transferServlet")
public class TransferServlet extends HttpServlet {
/**
* http mine,json类型
*/
public static final String MIME_TYPE_JSON = "application/json";
/**
* http mine,json类型指定utf-8编码
*/
public final static String MIME_TYPE_JSON_UTF8 = MIME_TYPE_JSON + ";charset=UTF-8";
//1.实例化TransferService
// private TransferService transferService = new TransferServcieImpl();
private TransferService transferService =(TransferService) BeanFactory.getBean("transferService");
...
}
service
public class TransferServcieImpl implements TransferService {
// private AccountDao accountDao = new AccountDaoImpl();
private AccountDao accountDao ;
/**
* 提供get,set方法
* @return
*/
public AccountDao getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
启动并把异常代码注释
执行成功,但打开异常代码后,还是不行的,因为没有事务控制在Service中
解决第二个大问题
- 在servcie中的select,update方法每次都会创建一个新的连接,这样不是一个Connection,
- 同时每次执行完都把连接关闭了,再次又要重新获取新连接
- 事务控制JDBC默认是在dao层Connection对象的,控制在Service层中,解决就是把事务控制放在Service中
####### 1.每次都创建新连接
一个请求到Server后就一个线程在处理,可不可把当前线程与Connection绑定在一起这样就解决了呢?
新建ConnectionUtils工具类来实现
/**
* @Description
* @ClassName ConnectionUtils
* @Author 刘楠
* @date 2020.06.24
*/
public class ConnectionUtils {
/**
* 单例
*/
private ConnectionUtils(){
}
private static ConnectionUtils connectionUtils = new ConnectionUtils();
/**
* 使用ThreadLocal与Connection绑定
*/
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
public static ConnectionUtils getInstance(){
return connectionUtils;
}
public Connection getCurrentConnection() throws SQLException {
//先直接从当前线程取
Connection connection =threadLocal.get();
//判断是否为空
if(connection==null){
//空就从工具类中创建一个连接Connection
connection = DruidUtils.getInstance().getConnection();
//Connection与当前线程绑定
threadLocal.set(connection);
}
//返回连接
return connection;
}
}
- Connection每次使用完都关闭了?我们不关闭就好了吗
改造Dao层
public class AccountDaoImpl implements AccountDao {
@Override
public Account queryByCardNo(String cardNo) throws SQLException {
//从连接池获取连接
// Connection connection = DruidUtils.getInstance().getConnection();
/**
* 获取当前线程的Connection
*/
Connection connection = ConnectionUtils.getInstance().getCurrentConnection();
System.out.println("queryByCardNo connection " + connection.toString());
String sql = "select name ,cardNo ,money from account where cardNo=?";
//预编译SQL
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//填充参数
preparedStatement.setString(1, cardNo);
//执行查询
ResultSet resultSet = preparedStatement.executeQuery();
Account account = null;
while (resultSet.next()) {
account = new Account();
account.setMoney(resultSet.getInt("money"));
account.setCardNo(resultSet.getString("cardNo"));
account.setName(resultSet.getString("name"));
}
preparedStatement.close();
//关闭后就不是当前线程了
// connection.close();
return account;
}
@Override
public int updateAccountByCardno(Account fAccount) throws SQLException {
// Connection connection = DruidUtils.getInstance().getConnection();
/**
* 获取当前线程的Connection
*/
Connection connection = ConnectionUtils.getInstance().getCurrentConnection();
System.out.println("updateAccountByCardno connection " + connection.toString());
String sql = "update account set money =? where cardNo=? ";
//预编译SQL
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置参数
preparedStatement.setInt(1, fAccount.getMoney());
preparedStatement.setString(2, fAccount.getCardNo());
//执行更新
int update = preparedStatement.executeUpdate();
preparedStatement.close();
//关闭后就不是当前线程了
// connection.close();
return update;
}
}
测试下Connection是不是同一个
发一个请求
改造Servcie层-使用手动事务-异常未开启
package com.liu.spring.service.impl;
import com.liu.spring.dao.AccountDao;
import com.liu.spring.dao.impl.AccountDaoImpl;
import com.liu.spring.entity.Account;
import com.liu.spring.factory.BeanFactory;
import com.liu.spring.service.TransferService;
import com.liu.spring.transaction.TransactionManager;
import com.liu.spring.util.ConnectionUtils;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @Description
* @ClassName TransferServcieImpl
* @Author 刘楠
* @date 2020.06.23
*/
public class TransferServcieImpl implements TransferService {
// private AccountDao accountDao = new AccountDaoImpl();
private AccountDao accountDao ;
@Override
public boolean transfer(String fromAccount, String toAccount, Integer money) throws Exception {
System.out.println("=====开始转账==== ");
try {
/**
* 开启事务关闭事务的自动提交
*/
ConnectionUtils.getInstance().getCurrentConnection().setAutoCommit(false);
Account fAccount = accountDao.queryByCardNo(fromAccount);
Account tAccount = accountDao.queryByCardNo(toAccount);
fAccount.setMoney(fAccount.getMoney()-money);
tAccount.setMoney(tAccount.getMoney()+money);
accountDao.updateAccountByCardno(fAccount);
//int i=1/0;
accountDao.updateAccountByCardno(tAccount);
/**
* 正常执行完成 提交事务
*/
ConnectionUtils.getInstance().getCurrentConnection().commit();
}catch (Exception e){
e.printStackTrace();
/**
* 有异常回滚事务
*/
ConnectionUtils.getInstance().getCurrentConnection().rollback();
//抛出异常 便于上层 捕获
throw new RuntimeException(e);
}
return true;
}
/**
* 提供get,set方法
* @return
*/
public AccountDao getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
}
测试下
打开异常代码
测试
重点看数据库
并没有出现最开始的现象
优化,将事务的开启,提交,回滚提取到一个公共类中
package com.liu.spring.transaction;
import com.liu.spring.util.ConnectionUtils;
import java.sql.SQLException;
/**
* @Description 负责手动事务的开启,提交 ,回滚
* @ClassName TransactionManager 事务管理器
* @Author 刘楠
* @date 2020.06.24
*/
public class TransactionManager {
private static TransactionManager INSTANCE = new TransactionManager();
private TransactionManager(){
}
public static TransactionManager getInstance(){
return INSTANCE;
}
/**
* 开启事务
*/
public void beginTransaction() throws SQLException {
ConnectionUtils.getInstance().getCurrentConnection().setAutoCommit(false);
}
/**
* 提交事务
*/
public void commitTransaction() throws SQLException {
ConnectionUtils.getInstance().getCurrentConnection().commit();
}
/**
* 回滚事务
*/
public void rollbackTransaction() throws SQLException {
ConnectionUtils.getInstance().getCurrentConnection().rollback();
}
}
改造Service
package com.liu.spring.service.impl;
import com.liu.spring.dao.AccountDao;
import com.liu.spring.dao.impl.AccountDaoImpl;
import com.liu.spring.entity.Account;
import com.liu.spring.factory.BeanFactory;
import com.liu.spring.service.TransferService;
import com.liu.spring.transaction.TransactionManager;
import com.liu.spring.util.ConnectionUtils;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @Description
* @ClassName TransferServcieImpl
* @Author 刘楠
* @date 2020.06.23
*/
public class TransferServcieImpl implements TransferService {
// private AccountDao accountDao = new AccountDaoImpl();
private AccountDao accountDao ;
@Override
public boolean transfer(String fromAccount, String toAccount, Integer money) throws Exception {
System.out.println("=====开始转账==== ");
try {
/**
* 开启事务关闭事务的自动提交
*/
// ConnectionUtils.getInstance().getCurrentConnection().setAutoCommit(false);
//使用事务管理器-开启使用
TransactionManager.getInstance().beginTransaction();
Account fAccount = accountDao.queryByCardNo(fromAccount);
Account tAccount = accountDao.queryByCardNo(toAccount);
fAccount.setMoney(fAccount.getMoney()-money);
tAccount.setMoney(tAccount.getMoney()+money);
accountDao.updateAccountByCardno(fAccount);
int i=1/0;
accountDao.updateAccountByCardno(tAccount);
/**
* 正常执行完成 提交事务
*/
// ConnectionUtils.getInstance().getCurrentConnection().commit();
//使用事务管理器-提交事务
TransactionManager.getInstance().commitTransaction();
}catch (Exception e){
e.printStackTrace();
/**
* 有异常回滚事务
*/
// ConnectionUtils.getInstance().getCurrentConnection().rollback();
//使用事务管理器回滚事务
TransactionManager.getInstance().rollbackTransaction();
//抛出异常 便于上层 捕获
throw new RuntimeException(e);
}
return true;
}
/**
* 提供get,set方法
* @return
*/
public AccountDao getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
}
再次测试异常情况
并没有改变,
测试下正常情况
注释异常代码
提交成功
这样事务就改选到Service中了,改造完成
代码:https://gitee.com/null_631_9084/myhomework/tree/master/stage01-spring/spring-classroom
还存在一些问题,后期优化
每个方法方法都有一大段try-catch代码不太友好