|
33 | 33 | ErrMultipleAuthOptionsPassed = fmt.Errorf("both password and useMsi=true were passed.") |
34 | 34 | ) |
35 | 35 |
|
36 | | -var lockErrorMap = map[mssql.ReturnStatus]string{ |
| 36 | +var lockErrorMap = map[int]string{ |
37 | 37 | -1: "The lock request timed out.", |
38 | 38 | -2: "The lock request was canceled.", |
39 | 39 | -3: "The lock request was chosen as a deadlock victim.", |
@@ -198,18 +198,24 @@ func (ss *SQLServer) Lock() error { |
198 | 198 | return err |
199 | 199 | } |
200 | 200 |
|
201 | | - // This will either obtain the lock immediately and return true, |
202 | | - // or return false if the lock cannot be acquired immediately. |
| 201 | + // This will block until the lock is acquired. |
203 | 202 | // MS Docs: sp_getapplock: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-getapplock-transact-sql?view=sql-server-2017 |
204 | | - query := `EXEC sp_getapplock @Resource = @p1, @LockMode = 'Update', @LockOwner = 'Session', @LockTimeout = 0` |
| 203 | + query := ` |
| 204 | + DECLARE @lockResult int; |
| 205 | + EXEC @lockResult = sp_getapplock @Resource = @p1, @LockMode = 'Exclusive', @LockOwner = 'Session', @LockTimeout = -1; |
| 206 | + SELECT @lockResult;` |
205 | 207 |
|
206 | | - var status mssql.ReturnStatus |
207 | | - if _, err = ss.conn.ExecContext(context.Background(), query, aid, &status); err == nil && status > -1 { |
| 208 | + var status int |
| 209 | + if err = ss.conn.QueryRowContext(context.Background(), query, aid).Scan(&status); err == nil && status > -1 { |
208 | 210 | return nil |
209 | 211 | } else if err != nil { |
210 | 212 | return &database.Error{OrigErr: err, Err: "try lock failed", Query: []byte(query)} |
211 | 213 | } else { |
212 | | - return &database.Error{Err: fmt.Sprintf("try lock failed with error %v: %v", status, lockErrorMap[status]), Query: []byte(query)} |
| 214 | + errorDescription, ok := lockErrorMap[status] |
| 215 | + if !ok { |
| 216 | + errorDescription = "Unknown error" |
| 217 | + } |
| 218 | + return &database.Error{Err: fmt.Sprintf("try lock failed with error %v: %v", status, errorDescription), Query: []byte(query)} |
213 | 219 | } |
214 | 220 | }) |
215 | 221 | } |
|
0 commit comments