|
2 | 2 |
|
3 | 3 | import java.sql.SQLException;
|
4 | 4 | import java.util.Date;
|
| 5 | +import java.util.concurrent.locks.ReentrantLock; |
5 | 6 |
|
6 | 7 | import com.genexus.*;
|
7 | 8 | import com.genexus.db.driver.DataSource;
|
@@ -164,10 +165,54 @@ public void executeBatch(int cursorIdx)
|
164 | 165 | {
|
165 | 166 | execute(cursorIdx, null, false);
|
166 | 167 | }
|
| 168 | + |
| 169 | + static ReentrantLock lockExecute = new ReentrantLock(); |
| 170 | + |
167 | 171 | public synchronized void execute(int cursorIdx, Object[] parms)
|
168 | 172 | {
|
169 |
| - execute(cursorIdx, parms, true); |
170 |
| - } |
| 173 | + DataSource ds = getDataSourceNoException(); |
| 174 | + if(ds!=null && ds.jdbcIntegrity==false) |
| 175 | + { |
| 176 | + // If the JDBC integrity is disabled (XBASE_TINT), SQLIte is in autocommit mode. |
| 177 | + // we need to lock the execute method to avoid concurrency issues. |
| 178 | + // for example, the postExecute method (select changes()) cause exception in Android SQLite. |
| 179 | + // it happends with execute sql statements like from diferent threads, like using procedures submit. |
| 180 | + Cursor cursor = cursors[cursorIdx]; |
| 181 | + if (cursor instanceof UpdateCursor) // if the cursor is an UpdateCursor, we need to lock the execute method. |
| 182 | + { |
| 183 | + AndroidLog.debug("execute UpdateCursor cursorIdx : " + cursorIdx); |
| 184 | + long timeStampStart = System.currentTimeMillis(); |
| 185 | + lockExecute.lock(); |
| 186 | + long timeStampLock = System.currentTimeMillis(); |
| 187 | + AndroidLog.debug("START execute UpdateCursor afterlock cursorIdx: " + cursorIdx + " Waiting time ms: " + (timeStampLock - timeStampStart)); |
| 188 | + try |
| 189 | + { |
| 190 | + // execute the cursor with the parameters. |
| 191 | + execute(cursorIdx, parms, true); |
| 192 | + } |
| 193 | + finally |
| 194 | + { |
| 195 | + lockExecute.unlock(); |
| 196 | + } |
| 197 | + long timeStampEnd = System.currentTimeMillis(); |
| 198 | + AndroidLog.debug("END execute UpdateCursor cursorIdx: " + cursorIdx+ " Execute time ms: " + (timeStampEnd - timeStampLock)); |
| 199 | + } |
| 200 | + else |
| 201 | + { |
| 202 | + // if the cursor is not an UpdateCursor, we can execute it without locking. |
| 203 | + long timeStampStart = System.currentTimeMillis(); |
| 204 | + execute(cursorIdx, parms, true); |
| 205 | + long timeStampEnd = System.currentTimeMillis(); |
| 206 | + AndroidLog.debug("END execute cursorIdx: " + cursorIdx+ " Execute time ms: " + (timeStampEnd - timeStampStart)); |
| 207 | + } |
| 208 | + } |
| 209 | + else |
| 210 | + { |
| 211 | + // default case, we execute the cursor with the parameters. |
| 212 | + execute(cursorIdx, parms, true); |
| 213 | + } |
| 214 | + |
| 215 | + } |
171 | 216 |
|
172 | 217 | private void execute(int cursorIdx, Object[] parms, boolean preExecute)
|
173 | 218 | {
|
|
0 commit comments