@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3/**
4 * Represents current transaction state of a connection.
5 */
6final class AphrontDatabaseTransactionState extends Phobject {
7
8 private $depth = 0;
9 private $readLockLevel = 0;
10 private $writeLockLevel = 0;
11
12 public function getDepth() {
13 return $this->depth;
14 }
15
16 public function increaseDepth() {
17 return ++$this->depth;
18 }
19
20 public function decreaseDepth() {
21 if ($this->depth == 0) {
22 throw new Exception(
23 pht(
24 'Too many calls to %s or %s!',
25 'saveTransaction()',
26 'killTransaction()'));
27 }
28
29 return --$this->depth;
30 }
31
32 public function getSavepointName() {
33 return 'Aphront_Savepoint_'.$this->depth;
34 }
35
36 public function beginReadLocking() {
37 $this->readLockLevel++;
38 return $this;
39 }
40
41 public function endReadLocking() {
42 if ($this->readLockLevel == 0) {
43 throw new Exception(
44 pht(
45 'Too many calls to %s!',
46 __FUNCTION__.'()'));
47 }
48 $this->readLockLevel--;
49 return $this;
50 }
51
52 public function isReadLocking() {
53 return ($this->readLockLevel > 0);
54 }
55
56 public function beginWriteLocking() {
57 $this->writeLockLevel++;
58 return $this;
59 }
60
61 public function endWriteLocking() {
62 if ($this->writeLockLevel == 0) {
63 throw new Exception(
64 pht(
65 'Too many calls to %s!',
66 __FUNCTION__.'()'));
67 }
68 $this->writeLockLevel--;
69 return $this;
70 }
71
72 public function isWriteLocking() {
73 return ($this->writeLockLevel > 0);
74 }
75
76 public function __destruct() {
77 if ($this->depth) {
78 throw new Exception(
79 pht(
80 'Process exited with an open transaction! The transaction '.
81 'will be implicitly rolled back. Calls to %s must always be '.
82 'paired with a call to %s or %s.',
83 'openTransaction()',
84 'saveTransaction()',
85 'killTransaction()'));
86 }
87 if ($this->readLockLevel) {
88 throw new Exception(
89 pht(
90 'Process exited with an open read lock! Call to %s '.
91 'must always be paired with a call to %s.',
92 'beginReadLocking()',
93 'endReadLocking()'));
94 }
95 if ($this->writeLockLevel) {
96 throw new Exception(
97 pht(
98 'Process exited with an open write lock! Call to %s '.
99 'must always be paired with a call to %s.',
100 'beginWriteLocking()',
101 'endWriteLocking()'));
102 }
103 }
104
105}