javaweb学习--事务管理
事务处理
1.事务管理在Dao层
2. 事务管理在业务层
实现:
涉及到的组件:
- OpenSessionInViewFilter
- TransactionManager
- ThreadLocal
- ConnUtil
- BaseDAO
(1)拦截器(OpenSessionInViewFilter)
package com.fruits.filters;
import com.fruits.trans.TransactionManager;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.sql.SQLException;
@WebFilter("*.do")
public class OpenSessionInViewFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
TransactionManager transactionManager = new TransactionManager();
try {
transactionManager.beginTrans(); // 开始事务
filterChain.doFilter(servletRequest,servletResponse); // 放行
transactionManager.commit(); //提交事务
} catch (SQLException e) {
e.printStackTrace();
try {
transactionManager.rollback(); //回滚事务
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
@Override
public void destroy() {
}
}
(2)封装事务操作
public class TransactionManager {
//该类用来封装事务的操作:开启事务、提交事务、关闭事务。。。
//开启事务
public void beginTrans() throws SQLException {
ConnUtil.getConn().setAutoCommit(false); //获取连接,不自动提交
}
//提交事务
public void commit() throws SQLException {
ConnUtil.getConn().commit();
ConnUtil.closeConn();
}
//回滚事务
public void rollback() throws SQLException {
ConnUtil.getConn().rollback();
ConnUtil.closeConn();
}
}
(3)获取数据库连接
package com.fruits.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnUtil {
public static final String driver = "com.mysql.cj.jdbc.Driver";
public static final String url =" jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8";
public static final String username =" root";
public static final String password = "123456";
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static Connection createConn(){
try {
//加载驱动
Class.forName(driver);
//通过驱动管理器获取连接对象
return DriverManager.getConnection(url,username,password);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Connection getConn(){
Connection conn = threadLocal.get(); //获取到Connection对象
if(conn == null){
conn = createConn(); //如果threadLocal为空,重新获取Connection对象
threadLocal.set(conn); //获取到Connection对象值就设置到threadLocal中
}
return threadLocal.get(); //重新获取到Connection对象
}
public static void closeConn() throws SQLException {
Connection conn = threadLocal.get(); //获取到Connection对象
if(conn == null){
return;
}
if(!conn.isClosed()){
conn.close();
threadLocal.set(null);
}
}
}
3. ThreadLocal
ThreadLocal 本地线程:同一个线程中进行数据通信。通过set方法在当前线程上存储数据、通过get方法在当前线程上获取数据
- set方法源码分析:
public void set(T value) {
Thread t = Thread.currentThread(); //获取当前的线程
ThreadLocalMap map = getMap(t); //每一个线程都维护各自的一个容器(ThreadLocalMap)
if (map != null)
map.set(this, value); //这里的key对应的是ThreadLocal,因为我们的组件中需要传输(共享)的对象可能会有多个(不止Connection)
else
createMap(t, value); //默认情况下map是没有初始化的,那么第一次往其中添加数据时,会去初始化
}
-get方法源码分析:
public T get() {
Thread t = Thread.currentThread(); //获取当前的线程
ThreadLocalMap map = getMap(t); //获取和这个线程(企业)相关的ThreadLocalMap(也就是工作纽带的集合)
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this); //this指的是ThreadLocal对象,通过它才能知道是哪一个工作纽带
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value; //entry.value就可以获取到工具箱了
return result;
}
}
return setInitialValue();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!