forked from mirror/gorm
Make Save, Delete, Updates be executed in transaction to keep data consistency
This commit is contained in:
parent
3d2128e743
commit
ce91468922
27
chain.go
27
chain.go
|
@ -50,8 +50,8 @@ func (s *Chain) deleteLastError() {
|
|||
s.Errors = s.Errors[:len(s.Errors)-1]
|
||||
}
|
||||
|
||||
func (s *Chain) do(value interface{}) (do *Do) {
|
||||
do = &Do{
|
||||
func (s *Chain) do(value interface{}) *Do {
|
||||
do := Do{
|
||||
chain: s,
|
||||
db: s.db,
|
||||
whereClause: s.whereClause,
|
||||
|
@ -67,7 +67,7 @@ func (s *Chain) do(value interface{}) (do *Do) {
|
|||
|
||||
s.value = value
|
||||
do.setModel(value)
|
||||
return
|
||||
return &do
|
||||
}
|
||||
|
||||
func (s *Chain) Model(model interface{}) *Chain {
|
||||
|
@ -132,12 +132,22 @@ func (s *Chain) Select(value interface{}) *Chain {
|
|||
}
|
||||
|
||||
func (s *Chain) Save(value interface{}) *Chain {
|
||||
s.do(value).save()
|
||||
do := s.do(value)
|
||||
tx_started := do.begin()
|
||||
do.save()
|
||||
if tx_started {
|
||||
do.commit()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Chain) Delete(value interface{}) *Chain {
|
||||
s.do(value).delete()
|
||||
do := s.do(value)
|
||||
tx_started := do.begin()
|
||||
do.delete()
|
||||
if tx_started {
|
||||
do.commit()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -146,7 +156,12 @@ func (s *Chain) Update(attrs ...interface{}) *Chain {
|
|||
}
|
||||
|
||||
func (s *Chain) Updates(values interface{}, ignore_protected_attrs ...bool) *Chain {
|
||||
s.do(s.value).setUpdateAttrs(values, ignore_protected_attrs...).update()
|
||||
do := s.do(s.value)
|
||||
tx_started := do.begin()
|
||||
do.setUpdateAttrs(values, ignore_protected_attrs...).update()
|
||||
if tx_started {
|
||||
do.commit()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
|
25
do.go
25
do.go
|
@ -84,11 +84,11 @@ func (s *Do) exec(sqls ...string) (err error) {
|
|||
return s.err(err)
|
||||
}
|
||||
|
||||
func (s *Do) save() (i interface{}) {
|
||||
func (s *Do) save() (value interface{}) {
|
||||
if s.model.primaryKeyZero() {
|
||||
return s.create()
|
||||
value = s.create()
|
||||
} else {
|
||||
return s.update()
|
||||
value = s.update()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ func (s *Do) prepareUpdateSql(results map[string]interface{}) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *Do) update() (i int64) {
|
||||
func (s *Do) update() (i interface{}) {
|
||||
update_attrs := s.updateAttrs
|
||||
if len(update_attrs) > 0 {
|
||||
var need_update bool
|
||||
|
@ -756,6 +756,23 @@ func (s *Do) autoMigrate() *Do {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *Do) begin() bool {
|
||||
if db, ok := s.db.(sql_db); ok {
|
||||
tx, err := db.Begin()
|
||||
if err == nil {
|
||||
s.db = interface{}(tx).(sql_common)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Do) commit() {
|
||||
if db, ok := s.db.(sql_tx); ok {
|
||||
s.err(db.Commit())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Do) initializeWithSearchCondition() {
|
||||
m := Model{data: s.value, do: s}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ func init() {
|
|||
// db, err = Open("mysql", "gorm:gorm@/gorm?charset=utf8&parseTime=True")
|
||||
// db, err = Open("sqlite3", "/tmp/gorm.db")
|
||||
// db.SetLogger(log.New(os.Stdout, "\r\n", 0))
|
||||
db.LogMode(true)
|
||||
// db.LogMode(true)
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("No error should happen when connect database, but got %+v", err))
|
||||
|
|
Loading…
Reference in New Issue