package com.itheima.util;
import java.sql.Connection;
import java.sql.SQLException;
//封装了所有与事务有关的方法
public class TransactionManager {
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
public static Connection getConnection(){
Connection conn = tl.get();
if(conn==null){//从当前线程中获取链接
conn = DBCPUtil.getConnection();
tl.set(conn);
}
return conn;
}
public static void startTransaction(){
try {
Connection conn = getConnection();
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(){
try {
Connection conn = getConnection();
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void commit(){
try {
Connection conn = getConnection();
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void release(){
try {
Connection conn = getConnection();
conn.close();
tl.remove();//从当前线程中解绑。 与服务器实现有关:服务器采用线程池。
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package com.itheima.util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.itheima.service.BusinessService;
import com.itheima.service.impl.BusinessServiceImpl;
//AOP
public class BeanFactory {
public static BusinessService getBusinessService(){
final BusinessService s = new BusinessServiceImpl();
BusinessService proxyS = (BusinessService)Proxy.newProxyInstance(s.getClass().getClassLoader(),
s.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
TransactionManager.startTransaction();
Object rtValue = method.invoke(s, args);
return rtValue;
} catch (Exception e) {
TransactionManager.rollback();
throw new RuntimeException(e);
} finally {
TransactionManager.commit();
TransactionManager.release();
}
}
});
return proxyS;
}
}
package com.itheima.service;
public interface BusinessService {
/**
* 转账
* @param sourceAccountName 转出账户
* @param targetAccontName 转入账户
* @param money 交易金额
*/
void transfer(String sourceAccountName,String targetAccontName,float money);
}
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.BusinessService;
//业务层控制事务
public class BusinessServiceImpl implements BusinessService {
private AccountDao dao = new AccountDaoImpl();
public void transfer(String sourceAccountName, String targetAccontName,
float money) {
Account sAccount = dao.findByName(sourceAccountName);
Account tAccount = dao.findByName(targetAccontName);
sAccount.setMoney(sAccount.getMoney() - money);
tAccount.setMoney(tAccount.getMoney() + money);
dao.updateAcount(sAccount);
// int i=1/0;
dao.updateAcount(tAccount);
}
}
package com.itheima.view;
import com.itheima.service.BusinessService;
import com.itheima.service.impl.BusinessServiceImpl;
import com.itheima.util.BeanFactory;
public class Client {
public static void main(String[] args) {
BusinessService s = BeanFactory.getBusinessService();
s.transfer("aaa", "bbb", 100);
}
}