文章目录
测试前准备:
这里就用我之前的blog数据库了哇,主要懒得在添加表了,将就着叭,所以就用用户寿命年龄代替银行转账事务的处理【手动滑稽】
core-code:核心代码:
public void transfer(Integer source_user_id, Integer target_user_id, int age_money) {
// 1. the source id;
blogUser source = iBlogUserDao.findById(source_user_id);
// 2. the target id;
blogUser target = iBlogUserDao.findById(target_user_id);
// 3. the source move the age;
source.setUser_age(source.getUser_age()-age_money);
// 4. the target fetch the source age;
target.setUser_age(target.getUser_age()+age_money);
// 5. update the source info;
iBlogUserDao.update_user(source);
// +: the throwing trouble:
// int psycho = 1/0; // psycho-to-神经病;
// 6. update the target info;
iBlogUserDao.update_user(target);
}
案例,实现用户寿命年龄的转移;(事务)
先看效果:
转移前:
操作事务:
as follows:
他的功能实现impl:
然后试着添加一个中断错误:重新操作:
就抛出异常了吧:ArithmeticException: / by zero
分析:
我印象里就晓得什么commit和rollback咯,大概就是要让这个转账操作原子性;
- 打开事务,
- 执行操作;
- 提交事务|| 或者, 发生异常,回滚事务操作;
- 返回结果;
- 释放资源;
引入THreadLocal(<ThreadLocal作用、场景、原理 - 简书 (jianshu.com)>):
有两个工具类:
// tech.jasonch.utils.connectionUtils.java
package tech.jasonch.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
// dao
@Repository("connUtils")
public class connectionUtils {
private ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
@Autowired
private DataSource dataSource;
// public void setDataSource(DataSource dataSource) {
// this.dataSource = dataSource;
// }//
public Connection getThreadConnection(){
// ctrl+alt+t: make the try/catch block;
// 1.
try {
Connection conn = threadLocal.get();
// 2. isNull
if(conn==null){
conn = dataSource.getConnection();
threadLocal.set(conn);
}
return conn;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public void removeConnection(){
threadLocal.remove();
}
}
// tech.jasonch.utils.transactionManager.java;
package tech.jasonch.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.sql.SQLException;
@Repository
public class transactionManager {
@Autowired
private connectionUtils connUtils;
// public void setConnUtils(connectionUtils connUtils) {
// this.connUtils = connUtils;
// }
public void beginTransaction(){
try {
connUtils.getThreadConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void commit(){
try {
connUtils.getThreadConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void rollback(){
try {
System.out.println("噢,很抱歉,发生了异常,事务操作终止噢~");
connUtils.getThreadConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void release(){
try {
// reBack to the conn-pool;
connUtils.getThreadConnection().close();
connUtils.removeConnection();// 解绑;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
业务实现方法:
/**
* commit & rollback// the package: tech.jasonch.service.impl.userServiceImpl.java;
* @param source_user_id
* @param target_user_id
* @param age_money
*/
public void transfer(Integer source_user_id, Integer target_user_id, int age_money) {
try {
//1. open the transaction
txManager.beginTransaction();
//2. go the func;
//
// 1. the source id;
blogUser source = iBlogUserDao.findById(source_user_id);
// 2. the target id;
blogUser target = iBlogUserDao.findById(target_user_id);
// 3. the source move the age;
source.setUser_age(source.getUser_age()-age_money);
// 4. the target fetch the source age;
target.setUser_age(target.getUser_age()+age_money);
// 5. update the source info;
iBlogUserDao.update_user(source);
// +: the throwing trouble:
int psycho = 1/0; // psycho-to-神经病;// here is one err may stop the transaction;
// 6. update the target info;
iBlogUserDao.update_user(target);
//
//3. commit the transaction;
txManager.commit();
//4. return the result;
} catch (Exception e) {
// rollback
txManager.rollback();
} finally {
// release;
txManager.release();
}
}
执行操作后:
说明事务处理成功啦here;再看看数据库中年龄:
也没有发生变化,successfully over;
总结:
在实现方法中:这里只展示了转账方法,还有很多业务操作需要加入事务操作的过程代码,也就大大增加了代码的后期维护修改困难程度;