Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring@Transactional&x27;无法使用调用处理程序_Spring_Transactions_Dynamic Proxy - Fatal编程技术网

Spring@Transactional&x27;无法使用调用处理程序

Spring@Transactional&x27;无法使用调用处理程序,spring,transactions,dynamic-proxy,Spring,Transactions,Dynamic Proxy,我有一个JDBC连接的代理链,PreparedStatement和语句 ConnectionProxy: public class HikariConnectionProxy implements InvocationHandler { private final HikariDataSource dataSource; private final Connection delegate; private boolean committed; public st

我有一个JDBC
连接的代理链
PreparedStatement
语句

ConnectionProxy:

public class HikariConnectionProxy implements InvocationHandler {
    private final HikariDataSource dataSource;
    private final Connection delegate;
    private boolean committed;

    public static Connection newInstance(HikariDataSource dataSource) throws SQLException {
        final Connection connection = dataSource.getConnection();
        return (Connection) Proxy.newProxyInstance(
                connection.getClass().getClassLoader(),
                connection.getClass().getInterfaces(),
                new HikariConnectionProxy(dataSource, connection)
        );
    }

    public static Connection newInstance(HikariDataSource dataSource, String username, String password) throws SQLException {
        final Connection connection = dataSource.getConnection(username, password);
        return (Connection) Proxy.newProxyInstance(
                connection.getClass().getClassLoader(),
                connection.getClass().getInterfaces(),
                new HikariConnectionProxy(dataSource, connection)
        );
    }

    private HikariConnectionProxy(HikariDataSource dataSource, Connection connection) throws SQLException {
        this.dataSource = dataSource;
        delegate = connection;
        checkAutoCommit();
    }

    private void checkAutoCommit() throws SQLException {
        if (!delegate.getAutoCommit()) {
            delegate.setAutoCommit(true);
        }
    }

    private void commit() throws SQLException {
        delegate.commit();
        committed = true;
    }

    private void close() throws SQLException {
      // some code here
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Void.TYPE == method.getReturnType()) {
            final String methodName = method.getName().toLowerCase();
            if ("close".equals(methodName)) {
                this.close();
                return null;
            } else if ("commit".equals(methodName)) {
                this.commit();
                return null;
            }
        } else if (PreparedStatement.class == method.getReturnType()) {
            return ServiceBusPreparedStatementProxy.newInstance((PreparedStatement) method.invoke(delegate, args));
        } else if (Statement.class == method.getReturnType()) {
            return ServiceBusStatementProxy.newInstance((Statement) method.invoke(delegate, args));
        }
        return method.invoke(delegate, args);
    }
}
语句代理:

public class ServiceBusStatementProxy implements InvocationHandler {
    final boolean toCheckUnsigned;
    final Statement delegate;

    public static Statement newInstance(Statement statement) throws SQLException {
        return (Statement) Proxy.newProxyInstance(
                statement.getClass().getClassLoader(),
                statement.getClass().getInterfaces(),
                new ServiceBusStatementProxy(statement, statement.getConnection().getMetaData().getDatabaseProductName())
        );
    }

    ServiceBusStatementProxy(Statement statement, String dbName) {
        String dbNameLowerCase = dbName.toLowerCase();
        toCheckUnsigned = dbNameLowerCase.contains("oracle") || dbNameLowerCase.contains("mysql") || dbNameLowerCase.contains("mariadb");
        delegate = statement;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return toCheckUnsigned && ResultSet.class == method.getReturnType()
                ? ServiceBusResultSetProxy.newInstance((ResultSet) method.invoke(delegate, args))
                : method.invoke(delegate, args);
    }
}
public class ServiceBusPreparedStatementProxy extends ServiceBusStatementProxy implements InvocationHandler {
    private static final Predicate<Runnable> isValidArithmetic = runnable -> {
        try {
            runnable.run();
            return true;
        } catch (ArithmeticException e) {
            return false;
        }
    };

    public static PreparedStatement newInstance(PreparedStatement preparedStatement) throws SQLException {
        return (PreparedStatement) Proxy.newProxyInstance(
                preparedStatement.getClass().getClassLoader(),
                preparedStatement.getClass().getInterfaces(),
                new ServiceBusPreparedStatementProxy(preparedStatement, preparedStatement.getConnection().getMetaData().getDatabaseProductName())
        );
    }

    private ServiceBusPreparedStatementProxy(Statement statement, String dbName) {
        super(statement, dbName);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (toCheckUnsigned && Void.TYPE == method.getReturnType()
                && args != null && args.length >= 3 && "setObject".equalsIgnoreCase(method.getName()) && args[1] != null) {
            Class<?> valueClass = args[1].getClass();
            if (BigInteger.class == valueClass) {
                BigInteger bigInt = (BigInteger) args[1];
                if (!isValidArithmetic.test(bigInt::longValueExact)) {
                    ((PreparedStatement) delegate).setString((Integer) args[0], bigInt.toString());
                    return null;
                }
            }
        }
        return super.invoke(proxy, method, args);
    }
}
PreparedStatementProxy:

public class ServiceBusStatementProxy implements InvocationHandler {
    final boolean toCheckUnsigned;
    final Statement delegate;

    public static Statement newInstance(Statement statement) throws SQLException {
        return (Statement) Proxy.newProxyInstance(
                statement.getClass().getClassLoader(),
                statement.getClass().getInterfaces(),
                new ServiceBusStatementProxy(statement, statement.getConnection().getMetaData().getDatabaseProductName())
        );
    }

    ServiceBusStatementProxy(Statement statement, String dbName) {
        String dbNameLowerCase = dbName.toLowerCase();
        toCheckUnsigned = dbNameLowerCase.contains("oracle") || dbNameLowerCase.contains("mysql") || dbNameLowerCase.contains("mariadb");
        delegate = statement;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return toCheckUnsigned && ResultSet.class == method.getReturnType()
                ? ServiceBusResultSetProxy.newInstance((ResultSet) method.invoke(delegate, args))
                : method.invoke(delegate, args);
    }
}
public class ServiceBusPreparedStatementProxy extends ServiceBusStatementProxy implements InvocationHandler {
    private static final Predicate<Runnable> isValidArithmetic = runnable -> {
        try {
            runnable.run();
            return true;
        } catch (ArithmeticException e) {
            return false;
        }
    };

    public static PreparedStatement newInstance(PreparedStatement preparedStatement) throws SQLException {
        return (PreparedStatement) Proxy.newProxyInstance(
                preparedStatement.getClass().getClassLoader(),
                preparedStatement.getClass().getInterfaces(),
                new ServiceBusPreparedStatementProxy(preparedStatement, preparedStatement.getConnection().getMetaData().getDatabaseProductName())
        );
    }

    private ServiceBusPreparedStatementProxy(Statement statement, String dbName) {
        super(statement, dbName);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (toCheckUnsigned && Void.TYPE == method.getReturnType()
                && args != null && args.length >= 3 && "setObject".equalsIgnoreCase(method.getName()) && args[1] != null) {
            Class<?> valueClass = args[1].getClass();
            if (BigInteger.class == valueClass) {
                BigInteger bigInt = (BigInteger) args[1];
                if (!isValidArithmetic.test(bigInt::longValueExact)) {
                    ((PreparedStatement) delegate).setString((Integer) args[0], bigInt.toString());
                    return null;
                }
            }
        }
        return super.invoke(proxy, method, args);
    }
}

您正在处理自动提交。。。不要。@M.Deinum我只是在从池借用连接时检查自动提交。当我仍然使用代理连接但不使用代理语句时,一切都正常。不,您不需要。您将其显式设置为
true
这不是一个检查,而是一个集合。使用Transactions时,不应将其设置为
true
。另外,你能详细说明什么不起作用吗?如果出现异常,请添加stacktrace。@M.Deinum删除了此代码,但这一点都没有帮助…至少它会清理代码并保持自动提交不变。问题的第二部分呢,什么不起作用?另外,如何使用这些调用处理程序为Hikari创建代理?