ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Filter和 ThreadLocal组合管理事务

2022-02-06 11:03:00  阅读:155  来源: 互联网

标签:try 事务 args ThreadLocal Filter printStackTrace connection sql catch


Filter和 ThreadLocal组合管理事务

注意!一定要把MySQL的引擎改成InnoDB,只有InnoDB支持事务。创建数据表的时候数据库引擎默认用的是MyISAM不支持事务。

修改my.ini中的default-storage-engine=INNODB

在未修改引擎前创建的表也需要修改引擎设置

alter table table_name engine=innodb;

使用 ThreadLocal 来确保所有 dao 操作都在同一个 Connection 连接对象中完成

在这里插入图片描述

JdbcUtils 工具类的修改

public class JdbcUtils {

    private static DruidDataSource dataSource;
    private static ThreadLocal<Connection> conn = new ThreadLocal<Connection>();

    static {
        Properties properties = new Properties();
        //读取配置文件
        InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            //从流中加载数据
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            //创建数据库连接池
            dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *获取数据库连接池的链接
     * 返回null说明获取连接失败
     */
    public static Connection getConnection(){
        Connection connection = conn.get();
        if(connection==null){
            try {
                connection = dataSource.getConnection();//从数据库连接池获取连接
                conn.set(connection);//保存到threadlocal对象中,供后面的jdbc操作使用
                connection.setAutoCommit(false);//设置为手动管理事务
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return  connection;
    }

    public static void rollBackAndClose() {
        Connection connection = conn.get();
        if(connection!=null){
            try {
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void commitAndClose() {
        Connection connection = conn.get();
        if(connection!=null){
            try {
                connection.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        // 一定要执行remove 操作,否则就会出错。(因为Tomcat 服务器底层使用了线程池技术)
        conn.remove();
    }
}

修改 BaseDao

public abstract class BaseDao<T> {

    //使用DbUtils操作数据库
    private QueryRunner queryRunner = new QueryRunner();
    private Class<T> type;

    // 获取T的Class对象,获取泛型的类型,泛型是在被子类继承时才确定
    public BaseDao() {
        // 获取子类的类型
        Class clazz = this.getClass();
        // 获取父类的类型
        // getGenericSuperclass()用来获取当前类的父类的类型
        // ParameterizedType表示的是带泛型的类型
        ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
        // 获取具体的泛型类型 getActualTypeArguments获取具体的泛型的类型
        // 这个方法会返回一个Type的数组
        Type[] types = parameterizedType.getActualTypeArguments();
        // 获取具体的泛型的类型·
        this.type = (Class<T>) types[0];
    }


    /**
     * 执行insert update delete
     * 返回-1说明执行失败
     * 返回其他表示影响的行数
     * @param sql   sql语句
     * @param args  参数
     * @return
     */
    public int update(String sql,Object ... args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.update(connection, sql, args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     *查询返回一个javaBean对象的sql语句
     * @param sql sql语句
     * @param args sql参数
     * @return
     */
    public T queryForOne(String sql,Object ...args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.query(connection, sql, new BeanHandler<T>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     *查询返回多个javaBean对象的sql语句
     * @param sql sql语句
     * @param args sql语句参数
     * @return
     */
    public List<T> queryForList(String sql, Object ...args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return  queryRunner.query(connection, sql, new BeanListHandler<T>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 返回执行一行一列的sql语句
     * @param sql sql语句
     * @param args sql对应的参数值
     * @return
     */
    public Object queryForSingleValue(String sql,Object ...args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.query(connection, sql, new ScalarHandler(), args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

使用Filter过滤器统一给所有的Service方法都加上try-catch来进行管理

在这里插入图片描述

将所有异常都统一交给Tomcat,让Tomcat展示友好的错误信息页面。

在 web.xml 中我们可以通过错误页面配置来进行管理。

<!--error-page 标签配置,服务器出错之后,自动跳转的页面-->
<error-page>
<!--error-code 是错误类型-->
<error-code>500</error-code>
<!--location 标签表示。要跳转去的页面路径-->
<location>/pages/error/error500.jsp</location>
</error-page>

<!--error-page 标签配置,服务器出错之后,自动跳转的页面-->
<error-page>
<!--error-code 是错误类型-->
<error-code>404</error-code>
<!--location 标签表示。要跳转去的页面路径-->
<location>/pages/error/error404.jsp</location>
</error-page>

标签:try,事务,args,ThreadLocal,Filter,printStackTrace,connection,sql,catch
来源: https://www.cnblogs.com/ekertree/p/15865361.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有