()
| 790 | } |
| 791 | |
| 792 | func (db *DB) beginTx() (*Tx, error) { |
| 793 | // Lock the meta pages while we initialize the transaction. We obtain |
| 794 | // the meta lock before the mmap lock because that's the order that the |
| 795 | // write transaction will obtain them. |
| 796 | db.metalock.Lock() |
| 797 | |
| 798 | // Obtain a read-only lock on the mmap. When the mmap is remapped it will |
| 799 | // obtain a write lock so all transactions must finish before it can be |
| 800 | // remapped. |
| 801 | db.mmaplock.RLock() |
| 802 | |
| 803 | // Exit if the database is not open yet. |
| 804 | if !db.opened { |
| 805 | db.mmaplock.RUnlock() |
| 806 | db.metalock.Unlock() |
| 807 | return nil, berrors.ErrDatabaseNotOpen |
| 808 | } |
| 809 | |
| 810 | // Exit if the database is not correctly mapped. |
| 811 | if db.data == nil { |
| 812 | db.mmaplock.RUnlock() |
| 813 | db.metalock.Unlock() |
| 814 | return nil, berrors.ErrInvalidMapping |
| 815 | } |
| 816 | |
| 817 | // Create a transaction associated with the database. |
| 818 | t := &Tx{} |
| 819 | t.init(db) |
| 820 | |
| 821 | if db.freelist != nil { |
| 822 | db.freelist.AddReadonlyTXID(t.meta.Txid()) |
| 823 | } |
| 824 | |
| 825 | // Unlock the meta pages. |
| 826 | db.metalock.Unlock() |
| 827 | |
| 828 | // Update the transaction stats. |
| 829 | if db.stats != nil { |
| 830 | db.statlock.Lock() |
| 831 | db.stats.TxN++ |
| 832 | db.stats.OpenTxN++ |
| 833 | db.statlock.Unlock() |
| 834 | } |
| 835 | |
| 836 | return t, nil |
| 837 | } |
| 838 | |
| 839 | func (db *DB) beginRWTx() (*Tx, error) { |
| 840 | // If the database was opened with Options.ReadOnly, return an error. |
no test coverage detected