http urls monitor.

tx.go 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright (c) 2012-present The upper.io/db authors. All rights reserved.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining
  4. // a copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to
  8. // permit persons to whom the Software is furnished to do so, subject to
  9. // the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be
  12. // included in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. package sqladapter
  22. import (
  23. "context"
  24. "database/sql"
  25. "sync/atomic"
  26. "upper.io/db.v3"
  27. "upper.io/db.v3/lib/sqlbuilder"
  28. )
  29. // DatabaseTx represents a database session within a transaction.
  30. type DatabaseTx interface {
  31. BaseDatabase
  32. PartialDatabase
  33. BaseTx
  34. }
  35. // BaseTx provides logic for methods that can be shared across all SQL
  36. // adapters.
  37. type BaseTx interface {
  38. db.Tx
  39. // Committed returns true if the transaction was already commited.
  40. Committed() bool
  41. }
  42. type databaseTx struct {
  43. Database
  44. BaseTx
  45. }
  46. // NewDatabaseTx creates a database session within a transaction.
  47. func NewDatabaseTx(db Database) DatabaseTx {
  48. return &databaseTx{
  49. Database: db,
  50. BaseTx: db.Transaction(),
  51. }
  52. }
  53. type baseTx struct {
  54. *sql.Tx
  55. committed atomic.Value
  56. }
  57. func newBaseTx(tx *sql.Tx) BaseTx {
  58. return &baseTx{Tx: tx}
  59. }
  60. func (b *baseTx) Committed() bool {
  61. committed := b.committed.Load()
  62. if committed != nil {
  63. return true
  64. }
  65. return false
  66. }
  67. func (b *baseTx) Commit() (err error) {
  68. err = b.Tx.Commit()
  69. if err != nil {
  70. return err
  71. }
  72. b.committed.Store(struct{}{})
  73. return nil
  74. }
  75. func (w *databaseTx) Commit() error {
  76. defer w.Database.Close() // Automatic close on commit.
  77. return w.BaseTx.Commit()
  78. }
  79. func (w *databaseTx) Rollback() error {
  80. defer w.Database.Close() // Automatic close on rollback.
  81. return w.BaseTx.Rollback()
  82. }
  83. // RunTx creates a transaction context and runs fn within it.
  84. func RunTx(d sqlbuilder.Database, ctx context.Context, fn func(tx sqlbuilder.Tx) error) error {
  85. tx, err := d.NewTx(ctx)
  86. if err != nil {
  87. return err
  88. }
  89. defer tx.Close()
  90. if err := fn(tx); err != nil {
  91. tx.Rollback()
  92. return err
  93. }
  94. return tx.Commit()
  95. }
  96. var (
  97. _ = BaseTx(&baseTx{})
  98. _ = DatabaseTx(&databaseTx{})
  99. )