| 125 | type storageCallback func() |
| 126 | |
| 127 | func store(st xi.Storage, sps []storageProcedure, cb storageCallback) (err error) { |
| 128 | var tx *sql.Tx |
| 129 | // BEGIN |
| 130 | if tx, err = st.Writer().Begin(); err != nil { |
| 131 | return |
| 132 | } |
| 133 | log.Debugf("started database tx %p", tx) |
| 134 | // ROLLBACK on failure |
| 135 | defer tx.Rollback() |
| 136 | // WRITE |
| 137 | for _, sp := range sps { |
| 138 | if err = sp(tx); err != nil { |
| 139 | return |
| 140 | } |
| 141 | } |
| 142 | // CALLBACK: MUST NOT FAIL |
| 143 | if cb != nil { |
| 144 | cb() |
| 145 | log.Debugf("invoked storage callback %p in tx %p", cb, tx) |
| 146 | } |
| 147 | // COMMIT |
| 148 | if err = tx.Commit(); err != nil { |
| 149 | log.WithError(err).Fatal("failed to commit storage transaction") |
| 150 | } |
| 151 | log.Debugf("committed database tx %p", tx) |
| 152 | return |
| 153 | } |
| 154 | |
| 155 | func errPass(err error) storageProcedure { |
| 156 | return func(_ *sql.Tx) error { |