diff --git a/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java b/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java index 74cdff1136a3..4c47831ccbd4 100644 --- a/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java +++ b/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java @@ -144,6 +144,9 @@ enum Transaction implements Status TransactionMarkedAsFailed( ClientError, "Transaction was marked as both successful and failed. Failure takes precedence and so this " + "transaction was rolled back although it may have looked like it was going to be committed" ), + TransactionTimedOut( ClientError, + "The transaction has not completed within the specified timeout. You may want to retry with a longer " + + "timeout." ), // database errors TransactionStartFailed( DatabaseError, diff --git a/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardException.java b/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardException.java index 3b94786d9e3d..ea5e314dde5b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardException.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardException.java @@ -19,11 +19,14 @@ */ package org.neo4j.kernel.guard; -public class GuardException extends RuntimeException +import org.neo4j.kernel.api.exceptions.Status; + +public abstract class GuardException extends RuntimeException implements Status.HasStatus { protected GuardException( final String message ) { super( message ); } + } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardOperationsCountException.java b/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardOperationsCountException.java deleted file mode 100644 index 005e4d33faf0..000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardOperationsCountException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2002-2016 "Neo Technology," - * Network Engine for Objects in Lund AB [http://neotechnology.com] - * - * This file is part of Neo4j. - * - * Neo4j is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.neo4j.kernel.guard; - -public class GuardOperationsCountException extends GuardException -{ - - private final long opsCount; - - public GuardOperationsCountException( final long opsCount ) - { - super( String.format( "max ops (ops=%d)", opsCount ) ); - this.opsCount = opsCount; - } - - public long getOpsCount() - { - return opsCount; - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardTimeoutException.java b/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardTimeoutException.java index ab62581330ce..f526c07065d8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardTimeoutException.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/guard/GuardTimeoutException.java @@ -19,12 +19,14 @@ */ package org.neo4j.kernel.guard; +import org.neo4j.kernel.api.exceptions.Status; + public class GuardTimeoutException extends GuardException { private final long overtime; - public GuardTimeoutException(String message, final long overtime ) + public GuardTimeoutException( String message, final long overtime ) { super( message ); this.overtime = overtime; @@ -34,4 +36,10 @@ public long getOvertime() { return overtime; } + + @Override + public Status status() + { + return Status.Transaction.TransactionTimedOut; + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/guard/TimeoutGuard.java b/community/kernel/src/main/java/org/neo4j/kernel/guard/TimeoutGuard.java index 8ef218a0a681..2d602001cdda 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/guard/TimeoutGuard.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/guard/TimeoutGuard.java @@ -21,6 +21,7 @@ import java.time.Clock; +import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.impl.api.KernelStatement; import org.neo4j.kernel.impl.api.KernelTransactionImplementation; import org.neo4j.logging.Log; @@ -46,20 +47,22 @@ public void check( KernelStatement statement ) check( statement.getTransaction() ); } - private void check (KernelTransactionImplementation transaction) + private void check( KernelTransactionImplementation transaction ) { - check( getMaxTransactionCompletionTime( transaction ), "Transaction timeout." ); + check( transaction, "Transaction timeout." ); } - private void check( long maxCompletionTime, String timeoutDescription ) + private void check( KernelTransactionImplementation transaction, String timeoutDescription ) { long now = clock.millis(); + long maxCompletionTime = getMaxTransactionCompletionTime( transaction ); if ( maxCompletionTime < now ) { - final long overtime = now - maxCompletionTime; + long overtime = now - maxCompletionTime; String message = timeoutDescription + " (Overtime: " + overtime + " ms)."; log.warn( message ); - throw new GuardTimeoutException(message, overtime ); + transaction.markForTermination( Status.Transaction.TransactionTimedOut ); + throw new GuardTimeoutException( message, overtime ); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/guard/TimeoutGuardTest.java b/community/kernel/src/test/java/org/neo4j/kernel/guard/TimeoutGuardTest.java index d3ba307c7173..1af67eadda33 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/guard/TimeoutGuardTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/guard/TimeoutGuardTest.java @@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit; import org.neo4j.kernel.api.KernelTransaction; +import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.security.AccessMode; import org.neo4j.kernel.impl.api.KernelStatement; import org.neo4j.kernel.impl.api.KernelTransactionImplementation; @@ -37,6 +38,8 @@ import org.neo4j.logging.Log; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; public class TimeoutGuardTest extends KernelTransactionTestBase @@ -64,6 +67,9 @@ public void detectTimedTransaction() check( timeoutGuard, kernelStatement, overtime, message ); + KernelTransactionImplementation transaction = kernelStatement.getTransaction(); + assertSame( Status.Transaction.TransactionTimedOut, transaction.getReasonIfTerminated() ); + logProvider.assertContainsMessageContaining( message ); } @@ -80,6 +86,9 @@ public void allowToProceedWhenTransactionTimeoutNotReached() timeoutGuard.check( kernelStatement ); + KernelTransactionImplementation transaction = kernelStatement.getTransaction(); + assertNull( transaction.getReasonIfTerminated() ); + logProvider.assertNoLoggingOccurred(); }