20
20
use Laudis \Neo4j \Databags \SessionConfiguration ;
21
21
use Laudis \Neo4j \Databags \Statement ;
22
22
use Laudis \Neo4j \Databags \TransactionConfiguration ;
23
+ use Laudis \Neo4j \Enum \TransactionState ;
24
+ use Laudis \Neo4j \Exception \ClientException ;
23
25
use Laudis \Neo4j \Exception \Neo4jException ;
24
26
use Laudis \Neo4j \ParameterHelper ;
25
27
use Laudis \Neo4j \Types \AbstractCypherSequence ;
40
42
*/
41
43
final class BoltUnmanagedTransaction implements UnmanagedTransactionInterface
42
44
{
43
- private bool $ isRolledBack = false ;
44
-
45
- private bool $ isCommitted = false ;
45
+ private TransactionState $ state = TransactionState::ACTIVE ;
46
46
47
47
/**
48
48
* @param FormatterInterface<T> $formatter
@@ -59,10 +59,26 @@ public function __construct(
59
59
private readonly SessionConfiguration $ config ,
60
60
private readonly TransactionConfiguration $ tsxConfig ,
61
61
private readonly BookmarkHolder $ bookmarkHolder
62
- ) {}
62
+ ) {
63
+ }
63
64
65
+ /**
66
+ * @throws ClientException|Throwable
67
+ */
64
68
public function commit (iterable $ statements = []): CypherList
65
69
{
70
+ if ($ this ->isFinished ()) {
71
+ switch ($ this ->state ) {
72
+ case TransactionState::TERMINATED :
73
+ throw new ClientException ("Can't commit, transaction has been terminated " );
74
+ case TransactionState::COMMITTED :
75
+ throw new ClientException ("Can't commit, transaction has already been committed " );
76
+ case TransactionState::ROLLED_BACK :
77
+ throw new ClientException ("Can't commit, transaction has already been rolled back " );
78
+ default :
79
+ }
80
+ }
81
+
66
82
// Force the results to pull all the results.
67
83
// After a commit, the connection will be in the ready state, making it impossible to use PULL
68
84
$ tbr = $ this ->runStatements ($ statements )->each (static function ($ list ) {
@@ -72,15 +88,15 @@ public function commit(iterable $statements = []): CypherList
72
88
});
73
89
74
90
$ this ->connection ->commit ();
75
- $ this ->isCommitted = true ;
91
+ $ this ->state = TransactionState:: COMMITTED ;
76
92
77
93
return $ tbr ;
78
94
}
79
95
80
96
public function rollback (): void
81
97
{
82
98
$ this ->connection ->rollback ();
83
- $ this ->isRolledBack = true ;
99
+ $ this ->state = TransactionState:: ROLLED_BACK ;
84
100
}
85
101
86
102
/**
@@ -109,7 +125,7 @@ public function runStatement(Statement $statement)
109
125
$ this ->config ->getAccessMode ()
110
126
);
111
127
} catch (Throwable $ e ) {
112
- $ this ->isRolledBack = true ;
128
+ $ this ->state = TransactionState:: TERMINATED ;
113
129
throw $ e ;
114
130
}
115
131
$ run = microtime (true );
@@ -140,35 +156,40 @@ public function runStatements(iterable $statements): CypherList
140
156
}
141
157
142
158
/**
143
- * @throws Neo4jException
159
+ * @param Neo4jException $e
144
160
*
145
161
* @return never
162
+ * @throws Neo4jException
163
+ *
146
164
*/
147
- private function handleMessageException (Neo4jException $ e ): void
165
+ private function handleMessageException (Neo4jException $ e ): never
148
166
{
149
167
$ exception = $ e ->getErrors ()[0 ];
150
168
if (!($ exception ->getClassification () === 'ClientError ' && $ exception ->getCategory () === 'Request ' )) {
151
169
$ this ->connection ->reset ();
152
170
}
153
- if (!$ this ->isFinished () && in_array ($ exception ->getClassification (), TransactionHelper::ROLLBACK_CLASSIFICATIONS )) {
154
- $ this ->isRolledBack = true ;
171
+ if (!$ this ->isFinished () && in_array (
172
+ $ exception ->getClassification (),
173
+ TransactionHelper::ROLLBACK_CLASSIFICATIONS
174
+ )) {
175
+ $ this ->state = TransactionState::ROLLED_BACK ;
155
176
}
156
177
157
178
throw $ e ;
158
179
}
159
180
160
181
public function isRolledBack (): bool
161
182
{
162
- return $ this ->isRolledBack ;
183
+ return $ this ->state == TransactionState:: ROLLED_BACK ;
163
184
}
164
185
165
186
public function isCommitted (): bool
166
187
{
167
- return $ this ->isCommitted ;
188
+ return $ this ->state == TransactionState:: COMMITTED ;
168
189
}
169
190
170
191
public function isFinished (): bool
171
192
{
172
- return $ this ->isRolledBack () || $ this -> isCommitted () ;
193
+ return $ this ->state != TransactionState:: ACTIVE ;
173
194
}
174
195
}
0 commit comments