()
| 837 | } |
| 838 | |
| 839 | func (db *DB) beginRWTx() (*Tx, error) { |
| 840 | // If the database was opened with Options.ReadOnly, return an error. |
| 841 | if db.readOnly { |
| 842 | return nil, berrors.ErrDatabaseReadOnly |
| 843 | } |
| 844 | |
| 845 | // Obtain writer lock. This is released by the transaction when it closes. |
| 846 | // This enforces only one writer transaction at a time. |
| 847 | db.rwlock.Lock() |
| 848 | |
| 849 | // Once we have the writer lock then we can lock the meta pages so that |
| 850 | // we can set up the transaction. |
| 851 | db.metalock.Lock() |
| 852 | defer db.metalock.Unlock() |
| 853 | |
| 854 | // Exit if the database is not open yet. |
| 855 | if !db.opened { |
| 856 | db.rwlock.Unlock() |
| 857 | return nil, berrors.ErrDatabaseNotOpen |
| 858 | } |
| 859 | |
| 860 | // Exit if the database is not correctly mapped. |
| 861 | if db.data == nil { |
| 862 | db.rwlock.Unlock() |
| 863 | return nil, berrors.ErrInvalidMapping |
| 864 | } |
| 865 | |
| 866 | // Create a transaction associated with the database. |
| 867 | t := &Tx{writable: true} |
| 868 | t.init(db) |
| 869 | db.rwtx = t |
| 870 | db.freelist.ReleasePendingPages() |
| 871 | return t, nil |
| 872 | } |
| 873 | |
| 874 | // removeTx removes a transaction from the database. |
| 875 | func (db *DB) removeTx(tx *Tx) { |
no test coverage detected