2012-11-16 2 views
4

json에서 파싱 된 데이터를 일괄 적으로 db에 삽입하려고합니다. 배치를 삽입하기 위해 벨로우즈 방법을 사용합니다. 문제는 그 mDbWritable.beginTransaction(); 실행하는 데 너무 오래 걸립니다. 보통 6 초를 좋아한다! 나는 어디에 문제가 있는지 모른다. 어떤 생각 때문에 너무 오래 실행 시간을 초래할 수 있습니까? 고마워.Android sqlite begintransaction이 너무 오래 실행되었습니다.

@Override 
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) 
     throws OperationApplicationException { 
    long start = System.currentTimeMillis(); 
    mDbWritable.beginTransaction(); 
    long time = System.currentTimeMillis() - start; 
    Alog.i(TAG, "Time applyBatch beginTransaction: " + time); 

    final int numOperations = operations.size(); 
    final ContentProviderResult[] results = new ContentProviderResult[numOperations]; 
    try { 
     for (int i = 0; i < numOperations; i++) { 
      results[i] = operations.get(i).apply(this, results, i); 
     } 

     mDbWritable.setTransactionSuccessful(); 

    } finally { 
     mDbWritable.endTransaction(); 
    } 
    return results; 
} 

로그의 일부 예 :

11-16 15:14:53.726: I/ApiProvider(21442): Time applyBatch beginTransaction: 6025 
11-16 15:15:00.713: I/ApiProvider(21442): Time applyBatch beginTransaction: 4940 
11-16 15:15:17.819: I/ApiProvider(21442): Time applyBatch beginTransaction: 8651 
11-16 15:15:45.346: I/ApiProvider(21442): Time applyBatch beginTransaction: 12672 
11-16 15:16:16.807: I/ApiProvider(21442): Time applyBatch beginTransaction: 12411 
11-16 15:16:45.685: I/ApiProvider(21442): Time applyBatch beginTransaction: 12247 
11-16 15:17:01.500: I/ApiProvider(21442): Time applyBatch beginTransaction: 12788 

편집 : JSON을 구문 분석 할 때 루프에서 배치를 적용 사용합니다. 예 : json의 각 항목에 대해 일괄 적으로 구문 분석하고 적용합니다. 일괄 처리에는 삽입, 업데이트, 삭제 작업이 포함됩니다. 여기

내가 반복하고 applyBatch

Cursor starredChannelsCursor = 
     mContentResolver.query(ApiContract.Channels.CONTENT_URI, 
           new String[] {BaseColumns._ID, ChannelsTable.ID, ChannelsTable.SLUG }, 
           ChannelsTable.IS_STARRED + "=?",new String[] { "1" }, null); 

String userName = mSettings.getUserName(); 

if (starredChannelsCursor != null && starredChannelsCursor.moveToFirst()) {  
    while (!starredChannelsCursor.isAfterLast()) { 
     String channelSlug = starredChannelsCursor.getString(2); 
     ChannelHandler channelHandler = new ChannelHandler(this); 
     URI channelApiUri = Constants.getChannelApiURI(channelSlug,userName); 
     //execute update make applybatch call 
     executeUpdate(channelApiUri, channelHandler); 

     starredChannelsCursor.moveToNext(); 
    } 
} 

if (starredChannelsCursor != null) { 
    starredChannelsCursor.close(); 
} 


/** 
* Make call to Uri, parse response and apply batch operations to 
* contentResolver 
* 
* @param apiUri 
* @param handler 
*   - handles parsing 
*/ 
private boolean executeUpdate(URI apiUri, AbstractJSONHandler handler) { 
    ApiResponse apiResponse = mHttpHelper.doHttpCall(apiUri); 

    ArrayList<ContentProviderOperation> batch = 
        new ArrayList<ContentProviderOperation>(); 

    if (apiResponse != null) { 
     batch = handler.parse(apiResponse); 
     Alog.v(TAG, "update user data from " + apiUri); 
    } 

    if (batch.size() > 0) { 
     try { 
      mContentResolver.applyBatch(ApiContract.CONTENT_AUTHORITY, batch); 
     } catch (Exception e) { 
      Alog.v(TAG, "Error: " + e.getMessage()); 
     } 
    } 
    return true; 
} 
+0

'numOperations'의 값은 무엇입니까? – waqaslam

+0

은 일반적으로 70을 좋아하지만 문제는 mDbWritable.beginTransaction()에 있습니다. 당신이 볼 수 있듯이이 메소드 실행의 시간을 측정합니다. 다른 부분은 빠르다 – vandzi

+0

나는 당신이 ** applyBatch ** 방법의 바깥 쪽에서 거래를해야한다고 생각한다. – waqaslam

답변

2

수있을 것으로 보인다 유일한 문제를 호출하는 방법 코드, 다른 스레드가 해제만을위한 대기 beginTransaction()과 시간 낭비를 호출하는 동안 다른 스레드가 동일한 잠금을 획득한다는 것입니다 자물쇠. 코드를보고 스레드를 관리하는 방법과 applyBatch(..) 메서드를 호출하는 스레드를 확인하십시오.

beginTransaction()의 호출 계층 구조를보고 SQLiteDatabase 클래스로 보는 것이 유용 할 수 있습니다.

+0

beginTransaction이 12 초 정도 차단 될 수 있는지 알 수 없습니다. 그것은 아마도 루프에서 apply batch를 호출하기 때문일 것이다.하지만 이전 트랜잭션이 끝난 후에 beginTransaction을 호출했기 때문에 그렇지 않아야한다. – vandzi

+0

SQLiteDatabase 클래스의 소스에 따르면 다른 스레드에서 액세스 할 경우 30 초 동안 차단 될 수도 있습니다. 'applyBatch (..)'메소드를 호출하는 코드를 제공 할 수 있습니까? –

+0

원래 질문에 applyBatch를 호출하는 코드를 추가했습니다. – vandzi

관련 문제