* subxact.__enter__() or subxact.enter() * * Start an explicit subtransaction. SPI calls within an explicit * subtransaction will not start another one, so you can atomically * execute many SPI calls and still get a controllable exception if * one of them fails. */
| 84 | * one of them fails. |
| 85 | */ |
| 86 | static PyObject * |
| 87 | PLy_subtransaction_enter(PyObject *self, PyObject *unused) |
| 88 | { |
| 89 | PLySubtransactionData *subxactdata; |
| 90 | MemoryContext oldcontext; |
| 91 | PLySubtransactionObject *subxact = (PLySubtransactionObject *) self; |
| 92 | |
| 93 | if (subxact->started) |
| 94 | { |
| 95 | PLy_exception_set(PyExc_ValueError, "this subtransaction has already been entered"); |
| 96 | return NULL; |
| 97 | } |
| 98 | |
| 99 | if (subxact->exited) |
| 100 | { |
| 101 | PLy_exception_set(PyExc_ValueError, "this subtransaction has already been exited"); |
| 102 | return NULL; |
| 103 | } |
| 104 | |
| 105 | subxact->started = true; |
| 106 | oldcontext = CurrentMemoryContext; |
| 107 | |
| 108 | subxactdata = (PLySubtransactionData *) |
| 109 | MemoryContextAlloc(TopTransactionContext, |
| 110 | sizeof(PLySubtransactionData)); |
| 111 | |
| 112 | subxactdata->oldcontext = oldcontext; |
| 113 | subxactdata->oldowner = CurrentResourceOwner; |
| 114 | |
| 115 | BeginInternalSubTransaction(NULL); |
| 116 | |
| 117 | /* Be sure that cells of explicit_subtransactions list are long-lived */ |
| 118 | MemoryContextSwitchTo(TopTransactionContext); |
| 119 | explicit_subtransactions = lcons(subxactdata, explicit_subtransactions); |
| 120 | |
| 121 | /* Caller wants to stay in original memory context */ |
| 122 | MemoryContextSwitchTo(oldcontext); |
| 123 | |
| 124 | Py_INCREF(self); |
| 125 | return self; |
| 126 | } |
| 127 | |
| 128 | /* |
| 129 | * subxact.__exit__(exc_type, exc, tb) or subxact.exit(exc_type, exc, tb) |
nothing calls this directly
no test coverage detected