Solon v2.7.5

三、事务的监听器与工具(及事务对接)

</> markdown

1、事务的助理工具 TranUtils

public final class TranUtils {
    //执行事务
    public static void execute(Tran tran, RunnableEx runnable) throws Throwable;
    //是否在事务中
    public static boolean inTrans();
    //是否在事务中且只读
    public static boolean inTransAndReadOnly();
    //监听事务(v2.5.9 后支持)
    public static void listen(TranListener listener) throws IllegalStateException;
    //获取链接
    public static Connection getConnection(DataSource ds) throws SQLException;
    //获取链接代理(方便,用于第三方框架事务对接)//v2.7.5 后支持
    public static Connection getConnectionProxy(DataSource ds) throws SQLException;
}

关于 TranUtils.execute 手动管理务事,可阅:《事务的注解与手动使用示例》

2、事务监听器 TranListener(v2.5.9 后支持)

public interface TranListener {
    //顺序位
    default int getIndex();
    //提交之前(可以出异常触发回滚)
    default void beforeCommit(boolean readOnly) throws Throwable;
    //完成之前
    default void beforeCompletion();
    //提交之后
    default void afterCommit();
    //完成之后
    default void afterCompletion(int status);
}

3、事务监听示例(v2.5.9 后支持)

@Component
public class UserService {
    @Inject
    UserDao userDao;
    
    //添加并使用事务
    @Tran
    public void addUserAndTran(User user){
        userDao.add(user);
        onUserAdd();
        
        //这里明确知道有事务
        TranUtils.listen(new TranListener() {
            @Override
            public void afterCompletion(int status) {
                System.err.println("---afterCompletion: " + status);
            }
        });
    }
    
    //添加(不使用事务)
    public vod addUser(User user){
        userDao.add(user);
        onUserAdd();
    }
    
    private void onUserAdd(){
        //这里不确定是否有事务,先判断下
        if(TranUtils.inTrans()){
            TranUtils.listen(new TranListener() {
                @Override
                public void afterCompletion(int status) {
                    System.err.println("---afterCompletion: " + status);
                }
            });
        }
    }
}

4、第三方框架事务对接示例

  • dbvisitor-solon-plugin
// dbvisitor 事务适配示例
public class SolonManagedDynamicConnection implements DynamicConnection {
    private DataSource dataSource;

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

    @Override
    public Connection getConnection() throws SQLException {
        return TranUtils.getConnectionProxy(dataSource);
    }

    @Override
    public void releaseConnection(Connection conn) throws SQLException {
        conn.close();
    }
}
  • mybatis-solon-plugin
// mybatis 事务适配示例
public class SolonManagedTransaction implements Transaction {
    DataSource dataSource;
    Connection connection;

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

    @Override
    public Connection getConnection() throws SQLException {
        if (connection == null) {
            connection = TranUtils.getConnectionProxy(dataSource);
        }

        return connection;
    }

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

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

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

    @Override
    public Integer getTimeout() throws SQLException {
        return null;
    }
}