/
DeadlockDocTest.java
132 lines (118 loc) · 3.91 KB
/
DeadlockDocTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Copyright (c) 2002-2017 "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 <http://www.gnu.org/licenses/>.
*/
package examples;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.Test;
import org.neo4j.function.Function;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.TransactionFailureException;
import org.neo4j.helpers.TransactionTemplate;
import org.neo4j.kernel.DeadlockDetectedException;
import org.neo4j.test.EmbeddedDatabaseRule;
public class DeadlockDocTest
{
@Rule
public EmbeddedDatabaseRule rule = new EmbeddedDatabaseRule( );
@Test
public void transactionWithRetries() throws InterruptedException
{
Object result = transactionWithRetry();
}
@Test
public void transactionWithTemplate() throws InterruptedException
{
GraphDatabaseService graphDatabaseService = rule.getGraphDatabaseService();
// START SNIPPET: template
TransactionTemplate template = new TransactionTemplate( ).retries( 5 ).backoff( 3, TimeUnit.SECONDS );
// END SNIPPET: template
// START SNIPPET: usage-template
Object result = template.with(graphDatabaseService).execute( new Function<Transaction, Object>()
{
@Override
public Object apply( Transaction transaction ) throws RuntimeException
{
Object result = null;
return result;
}
} );
// END SNIPPET: usage-template
}
private Object transactionWithRetry()
{
GraphDatabaseService graphDatabaseService = rule.getGraphDatabaseService();
// START SNIPPET: retry
Throwable txEx = null;
int RETRIES = 5;
int BACKOFF = 3000;
for ( int i = 0; i < RETRIES; i++ )
{
try ( Transaction tx = graphDatabaseService.beginTx() )
{
Object result = doStuff(tx);
tx.success();
return result;
}
catch ( Throwable ex )
{
txEx = ex;
// Add whatever exceptions to retry on here
if ( !(ex instanceof DeadlockDetectedException) )
{
break;
}
}
// Wait so that we don't immediately get into the same deadlock
if ( i < RETRIES - 1 )
{
try
{
Thread.sleep( BACKOFF );
}
catch ( InterruptedException e )
{
throw new TransactionFailureException( "Interrupted", e );
}
}
}
if ( txEx instanceof TransactionFailureException )
{
throw ((TransactionFailureException) txEx);
}
else if ( txEx instanceof Error )
{
throw ((Error) txEx);
}
else if ( txEx instanceof RuntimeException )
{
throw ((RuntimeException) txEx);
}
else
{
throw new TransactionFailureException( "Failed", txEx );
}
// END SNIPPET: retry
}
private Object doStuff( Transaction tx )
{
return null;
}
}