Cheug's Blog

当前位置:网站首页 / JAVA / 正文

简单转帐模拟

2019-06-24 / JAVA / 1079 次围观 / 0 次吐槽 /

方式一 无事务

AccountDaoImol.java

image.png

AccountServiceImpl.java

image.png

方式二 添加事务

AccountDaoImol.java

package daoimpl;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import DBUtils.C3p0DbUtils;
import dao.IAccountDao;
import model.Account;

public class AccountDaoimpl implements IAccountDao{
	private Connection con;
	private QueryRunner qr = new QueryRunner();
	
	public AccountDaoimpl() {}

	public AccountDaoimpl(Connection con) {
		this.con = con;
	}

	@Override
	public void updateAccount(String from, String to, double amount) throws SQLException {
		
		qr.update(con,"update account set money=money-? where name=?",amount,from);
		qr.update(con,"update account set money=money+? where name=?",amount,to);
	}

	@Override
	public Account findAccount(String name) throws SQLException {
		String sql = "select * from account where name=?";
		Account account = qr.query(con,sql, new BeanHandler<Account>(Account.class),name);
		return account;
	}

	@Override
	public void updateAccount(Account account) throws SQLException {
		String sql = "update account set money=? where id=?";
		qr.update(con,sql,account.getMoney(),account.getId());
	}

}

AccountServiceImpl.java

package serviceimpl;

import java.sql.Connection;
import java.sql.SQLException;

import DBUtils.C3p0DbUtils;
import dao.IAccountDao;
import daoimpl.AccountDaoimpl;
import model.Account;
import service.IAccountService;

public class AccountServiceimpl implements IAccountService{
	
	private IAccountDao accountDao = new AccountDaoimpl();
	@Override
	public void transfer(String from, String to, Double amount) {
		
		try {
			accountDao.updateAccount(from, to, amount);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void transfer1(String from, String to, Double amount) throws SQLException {
		Connection conn = C3p0DbUtils.getConnection(); 
		accountDao = new AccountDaoimpl(conn);
		try {
			//设置事务
			conn.setAutoCommit(false);
			//获取from信息 
			Account accountFrom = accountDao.findAccount(from);
			//获取to信息
			Account accountTo = accountDao.findAccount(to);

			//计算转账金额
			accountFrom.setMoney(accountFrom.getMoney() - amount);
			accountTo.setMoney(accountTo.getMoney() + amount);
			
			//更新数据库
			accountDao.updateAccount(accountFrom);
			accountDao.updateAccount(accountTo);
			
			//提交事务
			conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
			//回滚
			conn.rollback();
		}finally {
			conn.close();//关闭
		}
	}
	

}

ThreadLocal【本地线程】

ThreadLocal的设计:

public class ThreadLocal{
    private Map<Runnable,Object> container = new HashMap<Runnable,Object>();
    
    public void set(Object value){
            container.put(Thread.currentThread(),value);//用当前线程作为key
    }
    
    public Object get(){
            return container.get(Thread.currentThread());
    }
    
    public void remove(){
            container.remove(Thread.currentThread());
    }
}

总结:调用该类的get方法,永远返回当前线程放入的数据。线程局部变量。

方式三 在service 中使用本地线程连接

public class ManagerThreadLocal {
		//本地线程
		private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
		/**
		 * 获取本地线程中连接
		 */
		public static Connection getConnection() {
			try {
				//从线程对象里获取连接
				Connection conn = tl.get();
				//如果为空,则从数据源里获取
				if(conn == null) {
					//取连接
					conn = C3p0DbUtils.getConnection();
					//将连接存在本地线程中
					tl.set(conn);
				}
				return conn;
			} catch (Exception e) {
				// TODO: handle exception
			}
			return null;
		}
		/**
		 * 开启事务
		 */
		public static void beginTransaction() {
			try {
				getConnection().setAutoCommit(false);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/**
		 * 提交事务
		 */
		public static void commitTransaction() {
			try {
				getConnection().commit();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/**
		 * 回滚事务
		 */
		public static void rollback() {
			try {
				getConnection().rollback();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/**
		 * 关闭连接
		 */
		public static void close() {
			try {
				getConnection().close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
}

修改AccountDaoImpl代码

image.png

修改AccountServiceImpl代码

image.png


Powered By Cheug's Blog

Copyright Cheug Rights Reserved.