class DbTran extends DbTranNode implements TranNode {
    private final Tran meta;
    private final Map<DataSource, Connection> conMap = new HashMap<>();
    private final TranListenerSet listenerSet = new TranListenerSet();

    //事务状态
    private int status = TranListener.STATUS_UNKNOWN;

    /**
     * 监听
     */
    public void listen(TranListener listener) {
        listenerSet.add(listener);

        //到这里说明事务已经开始干活了；开始执行提前之前的事件
//        listener.beforeCommit(tran.getMeta().readOnly());
    }

    public Tran getMeta() {
        return meta;
    }

    public Connection getConnection(DataSource ds) throws SQLException {<FILL_FUNCTION_BODY>}

    public DbTran(Tran meta) {
        this.meta = meta;
    }

    public void execute(RunnableEx runnable) throws Throwable {

        try {
            //conMap 此时，还是空的
            //
            TranManager.currentSet(this);

            //conMap 会在run时产生
            //
            runnable.run();

            if (parent == null) {
                commit();
            }
        } catch (Throwable ex) {
            if (parent == null) {
                rollback();
            }

            throw Utils.throwableUnwrap(ex);
        } finally {
            TranManager.currentRemove();

            if (parent == null) {
                close();
            }
        }
    }

    @Override
    public void commit() throws Throwable {
        //提前前
        listenerSet.beforeCommit(meta.readOnly());
        listenerSet.beforeCompletion();

        //提交
        super.commit();

        for (Map.Entry<DataSource, Connection> kv : conMap.entrySet()) {
            kv.getValue().commit();
        }

        //提交后
        status = TranListener.STATUS_COMMITTED;
        TranManager.currentRemove(); //移除当前节点
        listenerSet.afterCommit();
    }

    @Override
    public void rollback() throws Throwable {
        super.rollback();
        for (Map.Entry<DataSource, Connection> kv : conMap.entrySet()) {
            kv.getValue().rollback();
        }

        //回滚后
        status = TranListener.STATUS_ROLLED_BACK;
    }

    @Override
    public void close() throws Throwable {
        try {
            super.close();
            for (Map.Entry<DataSource, Connection> kv : conMap.entrySet()) {
                try {
                    if (kv.getValue().isClosed() == false) {
                        kv.getValue().close();
                        //
                        // close 后，链接池会对 autoCommit,readOnly 状态进行还原
                        //
                    }
                } catch (Throwable e) {
                    log.warn(e.getMessage(), e);
                }
            }
        } finally {
            //关闭后（完成后）
            listenerSet.afterCompletion(status);
        }
    }
}

        if (conMap.containsKey(ds)) {
            return conMap.get(ds);
        } else {
            Connection con = ds.getConnection();
            con.setAutoCommit(false);
            con.setReadOnly(meta.readOnly());
            if (meta.isolation().level > 0) {
                con.setTransactionIsolation(meta.isolation().level);
            }

            conMap.putIfAbsent(ds, con);
            return con;
        }
    
<methods>public non-sealed void <init>() ,public void add(org.noear.solon.data.tran.TranNode) ,public void close() throws java.lang.Throwable,public void commit() throws java.lang.Throwable,public void rollback() throws java.lang.Throwable<variables>protected List<org.noear.solon.data.tran.impl.DbTranNode> children,static final org.slf4j.Logger log,protected org.noear.solon.data.tran.impl.DbTranNode parent