11.传统事务解决转账问题
步骤分析:
- 编写线程绑定工具类
- 编写事务管理器
- 修改service层代码
- 修改dao层代码
1.编写线程绑定工具类
@Component
public class ConnectionUtils {
private ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
@Autowired
private DataSource dataSource;
public Connection getThreadConnection(){
Connection connection = threadLocal.get();
if (connection == null ){
try {
connection = dataSource.getConnection();
threadLocal.set(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return connection;
}
public void removeThredConnection(){
threadLocal.remove();
}
}
2.编写事务管理器
@Component
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils;
public void beginTransacation(){
try {
connectionUtils.getThreadConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void conmmit(){
try {
connectionUtils.getThreadConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void rollback(){
try {
connectionUtils.getThreadConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void release(){
try {
connectionUtils.getThreadConnection().setAutoCommit(true);
connectionUtils.getThreadConnection().close();
connectionUtils.removeThredConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3. 修改Service层代码
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Autowired
private TransactionManager transactionManager;
@Override
public void transfer(String name1, String name2,Double money) {
try {
transactionManager.beginTransacation();
accountDao.out(name1,money);
int num = 100;
num = num / 0;
accountDao.in(name2 ,money );
transactionManager.conmmit();
}catch (Exception e){
e.printStackTrace();
transactionManager.rollback();
}finally {
transactionManager.release();
}
}
}
4.修改dao层代码
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Autowired
private QueryRunner queryRunner;
@Autowired
private ConnectionUtils connectionUtils;
@Override
public void out(String outUser, Double money) {
String sql = "update account set money = money - ? where name = ?";
try {
queryRunner.update(connectionUtils.getThreadConnection(), sql,money,outUser);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void in(String outUser, Double money) {
String sql = " update account set money = money + ? where name = ? ";
try {
queryRunner.update(connectionUtils.getThreadConnection(),sql,money,outUser);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5.结果
当出现异常时,资金并不会减少:
6.问题分析
上面代码,通过对业务层改造,已经可以实现事务控制了,但是由于我们添加了事务控制,也产生了一个新的问题: 业务层方法变得臃肿了,里面充斥着很多重复代码。并且业务层方法和事务控制方法耦合了,违背了面向对象的开发思想。
|