您的位置:首页 > 其它

ThreadLocal 开启事务

2015-12-25 14:59 274 查看
1、ThreadLocal该类提供了线程局部变量
2、分析原理:
ThreadLocal内部有一个Map。Map的key是当前线程对象,value是一个Object对象。
模拟该类:
public class ThreadLocal<T>{
private Map<Runnable,T> map = new HashMap<Runnable,T>();

public void set(T t){
map.put(Thread.currentThread(),t);
//把传入的参数绑定到当前线程上
}
public void remove(){
map.remove(Thread.currentThread());
//从当前线程上删除对象
}
public T get(){
return map.get(Thread.currentThread());
//获取当前线程上绑定的对象
}
}


dao层

package com.itheima.dao.impl;

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

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

import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import com.itheima.utils.TransactionManager;
/**

*
*/
public class AccountDaoImpl implements AccountDao {
private QueryRunner qr = new QueryRunner();

@Override
public Account getAccountByName(String accountName) {
try {
Account acc = qr.query(TransactionManager.getConnection(),"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName);
return acc;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

@Override
public void updateAccount(Account acc) {
try {
qr.update(TransactionManager.getConnection(),"update account set money=? where name=?", acc.getMoney(),acc.getName());
} catch (SQLException e) {
e.printStackTrace();
}

}

}


service层

package com.itheima.service.impl;

import com.itheima.dao.AccountDao;
import com.itheima.dao.impl.AccountDaoImpl;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import com.itheima.utils.TransactionManager;
/**
AOP:Aspect Object Program   (面向切面编程   面向方面编程)
名词介绍:
就是将事物的某个方面功能代码抽取出去集中做实现,在需要系统需要用的时候,就将方面代码织入(加入)到系统中,从而实现功能扩展
它打破了原有纵向继承体系结构(代码复用),可以在关键时候横向织入方面代码(代码复用)

实现原理:
动态代理模式

适合场景:事务控制  ,日志控制,权限管理,积分功能
* @author wangli
*
*/
public class AccountServiceImpl implements AccountService {

@Override
public void transfor(String sourceAcc, String targetAcc, float money) {

AccountDao dao = new AccountDaoImpl();
//1.根据源账户名,得到一个账户对象
Account srcAcc = dao.getAccountByName(sourceAcc);//非常关键,目的是确保dao中用的是同一个Connection对象
//2.目标对象名,得到一 个目标账户
Account tarAcc = dao.getAccountByName(targetAcc);
//3.更新余额
srcAcc.setMoney(srcAcc.getMoney()-money);//源账户减
tarAcc.setMoney(tarAcc.getMoney()+money);//目标账户加

//4.写入到表中
dao.updateAccount(srcAcc);
int i=1/0;

dao.updateAccount(tarAcc);

}

}


threadlocal

package com.itheima.utils;

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

/**
* 处理事务 的专门类
*                 也就是将这个事务处理的方面分离出来,形成一个独立的类
*
* 就是后面要说的方面代码
* @author wangli
*
*/
public class TransactionManager {

private static ThreadLocal<Connection> tL = new ThreadLocal<Connection>();//线程局部变量,用于放入Connection
/**
* 得到连接
* @return
*/
public static Connection getConnection(){
Connection con = tL.get();//从线程局部变量取出一个Connection   ----第一次没有值
if(con==null){
//-第一次没有值
con = C3P0Util.getConneciton();//从连接池中取出一个连接
tL.set(con);//放入一个连接到线程局部变量中
}
return con;
}

/**
* 开启事务
* @throws Exception
*/
public static void startTransaction() throws Exception{
Connection con = getConnection();
con.setAutoCommit(false);
}

/**
* 提交事务
* @throws Exception
*/
public static void commit() throws Exception{
Connection con = getConnection();
con.commit();
}

/**
* 回滚事务
* @throws Exception
*/
public static void rollback() throws Exception{
Connection con = getConnection();
con.rollback();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: