使用 ThreadLocal 来确保所有 dao 操作都在同一个 Connection 连接对象中完成
手写的JdbcUtils 工具类的修改:
public class JdbcUtils {
private static DruidDataSource dataSource ;
private static ThreadLocal<Connection> conns = new ThreadLocal<Connection>();
static {
try {
Properties properties = new Properties();
//读取jdbc. properties属性配置文件
InputStream inputStream = JdbcUtils.class.getClassLoader(). getResourceAsStream("jdbc.properties");
//从流中加载数据
properties.load( inputStream);
//创建数据库连接池
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource (properties);
} catch (Exception e) {
e. printStackTrace( );
}
}
/**
*获取数据库连接池中的连接
* @return 如果返回null,说明获取连接失败,有值就是获取连接成功
*/
public static Connection getConnection(){
Connection conn = conns.get();
if (conn == nu1l) {
try {
conn = dataSource. getConnection();//从数据库连接池中获取连接
conns . set(conn); //保存到ThreadLocal对象中,供后面的jdbc操作使用
conn. setAutoCommit(false); //设置为手动管理事务
} catch (SQLException e) {
e. printStackTrace();
}
return conn;
}
/**
*提交事务,并关闭释放连接
*/
public static void commi tAndClose(){
Connection connection = conns . get();
if (connection != null) { //如果不等于null,说明之前使用过连接,操作过数据库
try {
connection. commit(); //提交事务
} catch (SQLException e) {
e. printStackTrace();
} finally {
try {
connection.close(); //关闭连接,资源资源
} catch (SQLException e) {
e.printStackTrace();
//一定要执行remove操作,否则就会出错。(因为Tomcat服务器底层使用了线程池技术)
conns.remove( );
/**
*回滚事务,并关闭释放连接
*/
public static void rollbackAndClose(){
Connection connection = conns.get();
if (connection != null) { //如果不等于null,说明之前使用过连接,操作过数据库
try {
connection. rollback();//回滚事务
} catch (SQLException e) {
e.printStackTrace( );
} finally {
try {
connection.close(); //关闭连接,资源资源
} catch (SQLException e) {
e.printStackTrace();
}
}
// 一定要执行remove操作,否则就会出错。 (因为Tomcat服务器底层使用了线程池技术)
conns. remove();
}
}
使用 Filter 过滤器统一给所有的 Service 方法都加上 try-catch。来进行实现的管理。
注意:把异常抛给 Filter 过滤器
throw new RuntimeException(e);// 把异常抛给 Filter 过滤器