4

Spring と Hibernate で c3p0 ComboPooledDataSource を使用しています。思いついたソリューションは、コンストラクターで実際の Datasource を受け入れるカスタム Datasource クラスです。すべての責任を実際のデータソースに委任します。true に設定すると、locked が再び false になるまで getConnection() を待機させるロックされたブール値があります。

誰かが私のアプローチの欠陥を見ることができるか、それともより良い代替手段があるかどうか疑問に思っていましたか? ありがとう!

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;
    }
}   
4

2 に答える 2

2

いくつかの欠陥:

  1. フラグ変数へのアクセスを同期しないため、他のスレッドがその状態を確認する保証はありません。
  2. に戻るnullInterruptedException、呼び出し元のコードで診断が困難な例外が発生します。
  3. すでに存在する同期プリミティブを再実装しています。

断然最善の解決策は、データベースをいじくり回すときにアプリをシャットダウンすることです。

データベースがダウンしているときにアプリケーションをハングさせたままにしておきたい場合は、Semaphoreを参照してください。

于 2012-10-25T13:31:50.620 に答える
1

私には2つの懸念があります。

  1. 現在のコードはスレッドセーフではありません。
  2. ほとんどの重要なシステムでは、複数のアプリケーションインスタンスを使用する必要があります。ロックしても、他のインスタンスがDBに作用するのを防ぐことはできません。
于 2012-10-25T13:32:14.043 に答える