栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

手写mybatis(五):事务

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手写mybatis(五):事务

文末附有源码地址

博客为代码完成后才开始整理,展示的代码都是最终代码

介绍:

个人学习,代码写的不够好,有点乱
通过学习mybatis源码模拟实现Mybatis(在完善)
已实现:
crud(实现XML配置,注解配置写过一点,原理差不多不写了)、
事务、
数据库连接池、
动态sql(一部分,原理没问题了,以后有时间再完善)、
一级二级缓存

一、从使用开始

单独使用mybatis时,使用sqlsession来处理事务。你一定看过下面的代码:

SqlSession session = factory.openSession(true);
SqlSession session = factory.openSession();
session.commit();

为了实现mybatis事务,通过模仿mybatis写出下面几个类:

二、类

首先我们创造出TransactionFactory和Transaction接口。

public interface TransactionFactory {

    Transaction newTransaction(Connection conn, boolean autoCommit);

    Transaction newTransaction(DataSource dataSource, boolean autoCommit);

}

通过工厂TransactionFactory根据不同的配置创建出Transaction。

public interface Transaction {

    Connection getConnection() throws SQLException;


    void commit() throws SQLException;


    void rollback() throws SQLException;


    void close() throws SQLException;

    boolean isAutoCommit() throws SQLException;

    void setAutoCommit(boolean autoCommit);

}

而TransactionIsolationLevel是一个枚举类,定义了事务隔离级别。

NONE(Connection.TRANSACTION_NONE),
READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE),

我们创造JdbcTransaction 实现Transaction 接口:

public class JdbcTransaction implements Transaction {
    protected Connection connection;
    protected DataSource dataSource;
    protected TransactionIsolationLevel level;
    protected boolean autoCommit;

    public JdbcTransaction(Connection conn, boolean autoComm) {
        this.connection = conn;
        this.autoCommit = autoComm;
    }

    public JdbcTransaction(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
        dataSource = ds;
        level = desiredLevel;
        autoCommit = desiredAutoCommit;
    }

    @Override
    public Connection getConnection() throws SQLException {
        if (connection == null) {
            openConnection();
        }
        return connection;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    @Override
    public void commit() throws SQLException {
        connection.commit();
    }

    @Override
    public void rollback() throws SQLException {
        connection.rollback();
    }

    @Override
    public void close() throws SQLException {
        if (connection != null) {
            
            resetAutoCommit();
            connection.close();
        }
    }

    protected void resetAutoCommit() {
        try {
            if (!connection.getAutoCommit()) {

                connection.setAutoCommit(true);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    protected void openConnection() throws SQLException {
        connection = dataSource.getConnection();
        if (level != null) {
            connection.setTransactionIsolation(level.getLevel());
        }
        setDesiredAutoCommit(autoCommit);
    }

    protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
        try {
            if (connection.getAutoCommit() != desiredAutoCommit) {
                connection.setAutoCommit(desiredAutoCommit);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public TransactionIsolationLevel getLevel() {
        return level;
    }

    public void setLevel(TransactionIsolationLevel level) {
        this.level = level;
    }

    @Override
    public boolean isAutoCommit() {
        return autoCommit;
    }

    @Override
    public void setAutoCommit(boolean autoCommit) {
        this.autoCommit = autoCommit;
    }
}

将DataSource置于JdbcTransaction 中,关闭连接是调用事务的方法。

private void release(Connection con, PreparedStatement pstm, ResultSet rs) {
        if (con != null) {
            try {
                if (transaction.isAutoCommit()) {
                    transaction.close();
                }

            } catch (Exception e) {
                throw new MybatisException("资源释放异常", e);
            }
        }
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                throw new MybatisException("资源释放异常", e);
            }
        }

        if (pstm != null) {
            try {
                pstm.close();
            } catch (Exception e) {
                throw new MybatisException("资源释放异常", e);
            }
        }
    }
 @Override
    public void close() {
        localCache.clear();
        try {
            transaction.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void clearLocalCache() {
        if (!closed) {
            localCache.clear();
        }
    }

    @Override
    public void rollback() {
        try {
            transaction.rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void commit() {
        try {
            transaction.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

最终在Executor中执行事务的各种操作。

项目地址

github:https://github.com/Alice-175/Mybaits

gitee:https://gitee.com/alice-175/Mybaits

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/462854.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号