我正在恢复数据库,我需要在执行此操作时从我的Java应用程序中锁定任何活动

时间:2012-10-25 13:20:13

标签: java spring hibernate

我正在使用带有Spring和Hibernate的c3p0 ComboPooledDataSource,我提出的解决方案是一个自定义Datasource类,它接受构造函数中的实际Datasource。我将所有责任委托给实际的数据源。我有一个锁定的布尔值,当设置为true时,getConnection()等待,直到锁定为false。

我只是想知道是否有人能看到我的方法存在缺陷或者有更好的选择?谢谢!

public interface LockableDataSource extends DataSource {
    public boolean isLocked();

    public void setLocked(boolean locked);
}


public class LockableDataSourceImpl implements LockableDataSource{

    private DataSource dataSource;
    private boolean locked = false;


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

    public Connection getConnection() throws SQLException {
        while(locked){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return dataSource.getConnection();
    }

    public Connection getConnection(String s, String s1) throws SQLException {
        while(locked){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return dataSource.getConnection(s, s1);
    }

    public PrintWriter getLogWriter() throws SQLException {
        return dataSource.getLogWriter();
    }

    public void setLogWriter(PrintWriter printWriter) throws SQLException {
        dataSource.setLogWriter(printWriter);
    }

    public void setLoginTimeout(int i) throws SQLException {
        dataSource.setLoginTimeout(i);
    }

    public int getLoginTimeout() throws SQLException {
        return dataSource.getLoginTimeout();
    }

    public <T> T unwrap(Class<T> tClass) throws SQLException {
        return dataSource.unwrap(tClass);
    }

    public boolean isWrapperFor(Class<?> aClass) throws SQLException {
        return dataSource.isWrapperFor(aClass);
    }

    public boolean isLocked() {
        return locked;
    }

    synchronized public void setLocked(boolean locked) {
        this.locked = locked;
    }
}   

2 个答案:

答案 0 :(得分:2)

有几个缺陷:

  1. 您不会同步对您的标志变量的访问,因此您无法保证其他线程看到其状态。
  2. 您在null上返回InterruptedException,这将导致调用代码中出现难以诊断的异常。
  3. 您正在重新实现已存在的同步原语。
  4. 到目前为止,最好的解决方案是在使用数据库时关闭您的应用程序。

    如果您确实希望在数据库关闭时暂停应用程序,请查看Semaphore

答案 1 :(得分:1)

我会有两个问题。

  1. 当前代码不是线程安全的。
  2. 大多数非平凡的系统都需要使用多个应用程序实例。您的锁不会阻止其他实例对数据库执行操作。