github.com/nakagami/firebirdsql@v0.9.10/transaction.go (about) 1 /******************************************************************************* 2 The MIT License (MIT) 3 4 Copyright (c) 2013-2019 Hajime Nakagami 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy of 7 this software and associated documentation files (the "Software"), to deal in 8 the Software without restriction, including without limitation the rights to 9 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 the Software, and to permit persons to whom the Software is furnished to do so, 11 subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in all 14 copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 *******************************************************************************/ 23 24 package firebirdsql 25 26 type firebirdsqlTx struct { 27 fc *firebirdsqlConn 28 isolationLevel int 29 isAutocommit bool 30 transHandle int32 31 needBegin bool 32 } 33 34 func (tx *firebirdsqlTx) begin() (err error) { 35 var tpb []byte 36 switch tx.isolationLevel { 37 case ISOLATION_LEVEL_READ_COMMITED_LEGACY: 38 tpb = []byte{ 39 byte(isc_tpb_version3), 40 byte(isc_tpb_write), 41 byte(isc_tpb_wait), 42 byte(isc_tpb_read_committed), 43 byte(isc_tpb_no_rec_version), 44 } 45 case ISOLATION_LEVEL_READ_COMMITED: 46 tpb = []byte{ 47 byte(isc_tpb_version3), 48 byte(isc_tpb_write), 49 byte(isc_tpb_wait), 50 byte(isc_tpb_read_committed), 51 byte(isc_tpb_rec_version), 52 } 53 case ISOLATION_LEVEL_REPEATABLE_READ: 54 tpb = []byte{ 55 byte(isc_tpb_version3), 56 byte(isc_tpb_write), 57 byte(isc_tpb_wait), 58 byte(isc_tpb_concurrency), 59 } 60 case ISOLATION_LEVEL_SERIALIZABLE: 61 tpb = []byte{ 62 byte(isc_tpb_version3), 63 byte(isc_tpb_write), 64 byte(isc_tpb_wait), 65 byte(isc_tpb_consistency), 66 } 67 case ISOLATION_LEVEL_READ_COMMITED_RO: 68 tpb = []byte{ 69 byte(isc_tpb_version3), 70 byte(isc_tpb_read), 71 byte(isc_tpb_wait), 72 byte(isc_tpb_read_committed), 73 byte(isc_tpb_rec_version), 74 } 75 } 76 err = tx.fc.wp.opTransaction(tpb) 77 if err != nil { 78 return 79 } 80 tx.transHandle, _, _, err = tx.fc.wp.opResponse() 81 tx.needBegin = false 82 tx.fc.transactionSet[tx] = struct{}{} 83 return 84 } 85 86 func (tx *firebirdsqlTx) commitRetainging() (err error) { 87 err = tx.fc.wp.opCommitRetaining(tx.transHandle) 88 if err != nil { 89 return 90 } 91 _, _, _, err = tx.fc.wp.opResponse() 92 tx.isAutocommit = tx.fc.isAutocommit 93 return 94 } 95 96 func (tx *firebirdsqlTx) Commit() (err error) { 97 err = tx.fc.wp.opCommit(tx.transHandle) 98 if err != nil { 99 return err 100 } 101 _, _, _, err = tx.fc.wp.opResponse() 102 tx.isAutocommit = tx.fc.isAutocommit 103 tx.needBegin = true 104 return 105 } 106 107 func (tx *firebirdsqlTx) Rollback() (err error) { 108 err = tx.fc.wp.opRollback(tx.transHandle) 109 if err != nil { 110 return nil 111 } 112 _, _, _, err = tx.fc.wp.opResponse() 113 tx.isAutocommit = tx.fc.isAutocommit 114 tx.needBegin = true 115 return 116 } 117 118 func newFirebirdsqlTx(fc *firebirdsqlConn, isolationLevel int, isAutocommit bool, withBegin bool) (tx *firebirdsqlTx, err error) { 119 tx = new(firebirdsqlTx) 120 tx.fc = fc 121 tx.isolationLevel = isolationLevel 122 tx.isAutocommit = isAutocommit 123 tx.needBegin = false 124 125 if withBegin { 126 err = tx.begin() 127 128 if err != nil { 129 return nil, err 130 } 131 132 } else { 133 tx.needBegin = true 134 } 135 136 return 137 }