[DBFLUTE-207] {Java}: 初期化処理が同時に走ると処理が途中で停止することがある Created: 2008-02-18 Updated: 2008-03-01 Resolved: 2008-02-25 |
|
| Status: | Closed |
| Project: | DBFlute |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | skirnir | Assignee: | jflute |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Environment: |
DBFulute 0.5.7-SNAPSHOT |
||
| Description |
|
アプリケーションを起動した後、複数スレッドからDaoのメソッドを同時に呼び出すなどしてDBFlute(&S2Dao)の初期化処理を同一タイミングで走らせるようにすると、処理が途中で停止することがある。 具体的には、Webアプリケーションで起動して最初に同時アクセスを行なったところ、ConditionBeanContext#addColumnAliasInfo()の156行目で処理が停止してしまった。 原因は以下のように推測される:
なおデバッガを仕掛けて追っていくことができない環境だったため、上記仮説が正しいかは不明です。 |
| Comments |
| Comment by jflute [ 2008-02-18 ] |
|
DaoMetaDataFactoryの対応だけS2Dao-1.0.47のみ対応とします。 |
| Comment by jflute [ 2008-02-18 ] |
|
ご報告ありがとうございます。 ソースを追っかけたところ、その他怪しい部分が幾つかありました。
// DaoMetaDataFactory public DaoMetaData getDaoMetaData(final Class daoClass) { if (!initialized) { DisposableUtil.add(this); initialized = true; } final String key = daoClass.getName(); // [A] DaoMetaData dmd = getSynchronizedDaoMetaDataCache(key); // [B] if (dmd != null) { return dmd; } // [C] synchronized (_daoMetaDataInitializationLockMonitor) {// One Thread Only Entered // [D] dmd = getSynchronizedDaoMetaDataCache(key); // [E] if (dmd != null) { // The second thread that stops at [C] can find // because the first thread have already initialized. if (_log.isDebugEnabled()) { _log.debug("...Getting daoMetaData as cache because the previous thread have already initilized."); } return dmd; } // [F] if (_log.isDebugEnabled()) { _log.debug("...Initializing daoMetaData."); } final DaoMetaData dmdi = createDaoMetaData(daoClass); putSynchronizedDaoMetaDataCache(key, dmdi); } // [G] dmd = getSynchronizedDaoMetaDataCache(key); if (dmd != null) { if (_log.isDebugEnabled()) { _log.debug("...Confirming that daoMetaData have been certainly initialized and cached."); } return dmd; } String msg = "The cache should have data meta data here: key=" + key + " cache=" + daoMetaDataCache; throw new IllegalStateException(msg); } // DaoMetaData public SqlCommand getSqlCommand(String methodName) throws MethodNotFoundRuntimeException { SqlCommand cmd = (SqlCommand) sqlCommands.get(methodName); if (cmd != null) { return cmd; } if (_internalDebug) { _log.debug("...Initializing sqlCommand: " + methodName); } synchronized (_methodInitializationLockMonitor) { cmd = (SqlCommand) sqlCommands.get(methodName); if (cmd != null) { return cmd; } cmd = initializeSqlCommand(methodName); } return cmd; } |