use transactions in Write(Command)Action async case

This commit is contained in:
peter
2016-03-15 13:18:13 +01:00
parent 0cd34a9b5d
commit 621f51c5ee
2 changed files with 38 additions and 16 deletions
@@ -30,25 +30,36 @@ public abstract class WriteAction<T> extends BaseActionRunnable<T> {
final RunResult<T> result = new RunResult<T>(this);
final Application application = ApplicationManager.getApplication();
if (application.isWriteAccessAllowed()) {
result.run();
boolean dispatchThread = application.isDispatchThread();
if (dispatchThread) {
AccessToken token = start(getClass());
try {
result.run();
} finally {
token.finish();
}
return result;
}
boolean dispatchThread = application.isDispatchThread();
if (!dispatchThread && application.isReadAccessAllowed()) {
if (application.isReadAccessAllowed()) {
LOG.error("Must not start write action from within read action in the other thread - deadlock is coming");
}
application.invokeAndWait(new Runnable() {
@Override
public void run() {
AccessToken token = application.acquireWriteActionLock(WriteAction.this.getClass());
AccessToken transaction = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.ANY_CHANGE);
try {
result.run();
AccessToken token = start(WriteAction.this.getClass());
try {
result.run();
}
finally {
token.finish();
}
}
finally {
token.finish();
transaction.finish();
}
}
}, ModalityState.defaultModalityState());
@@ -72,21 +72,32 @@ public abstract class WriteCommandAction<T> extends BaseActionRunnable<T> {
@Override
public RunResult<T> execute() {
Application application = ApplicationManager.getApplication();
if (!application.isDispatchThread() && application.isReadAccessAllowed()) {
final boolean dispatchThread = application.isDispatchThread();
if (!dispatchThread && application.isReadAccessAllowed()) {
LOG.error("Must not start write action from within read action in the other thread - deadlock is coming");
throw new IllegalStateException();
}
final RunResult<T> result = new RunResult<T>(this);
try {
application.invokeAndWait(new Runnable() {
@Override
public void run() {
performWriteCommandAction(result);
}
}, ModalityState.defaultModalityState());
if (dispatchThread) {
performWriteCommandAction(result);
} else {
try {
application.invokeAndWait(new Runnable() {
@Override
public void run() {
AccessToken token = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.ANY_CHANGE);
try {
performWriteCommandAction(result);
}
finally {
token.finish();
}
}
}, ModalityState.defaultModalityState());
}
catch (ProcessCanceledException ignored) { }
}
catch (ProcessCanceledException ignored) { }
return result;
}