Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
485a2cfc
Commit
485a2cfc
authored
Aug 07, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
79f54dcb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
39 additions
and
45 deletions
+39
-45
go/transaction/api.go
go/transaction/api.go
+21
-25
go/transaction/transaction.go
go/transaction/transaction.go
+11
-12
go/transaction/transaction_test.go
go/transaction/transaction_test.go
+7
-8
No files found.
go/transaction/api.go
View file @
485a2cfc
...
...
@@ -123,14 +123,14 @@ import (
type
Status
int
const
(
Active
Status
=
iota
// transaction is in progress
Committing
// transaction commit started
Committed
// transaction commit finished successfully
// XXX CommitFailed // transaction commit resulted in error
Aborting
// transaction abort started
Aborted
// transaction was aborted by user
// XXX AbortFailed ? // transaction abort resulted in error
// XXX Doomed // transaction was doomed
Active
Status
=
iota
// transaction is in progress
Committing
// transaction commit started
Committed
// transaction commit finished successfully
// XXX CommitFailed
// transaction commit resulted in error
Aborting
// transaction abort started
Aborted
// transaction was aborted by user
// XXX AbortFailed ?
// transaction abort resulted in error
// XXX Doomed
// transaction was doomed
)
// Transaction represents a transaction.
...
...
@@ -140,15 +140,14 @@ const (
// Before completion, if there are changes to managed data, corresponding
// DataManager(s) must join the transaction to participate in the completion.
type
Transaction
interface
{
User
()
string
// user name associated with transaction
Description
()
string
// description of transaction
User
()
string
// user name associated with transaction
Description
()
string
// description of transaction
// XXX map[string]interface{} (objects must be simple values serialized with pickle or json, not "instances")
Extension
()
string
// XXX +Note, SetUser, ...
// Status returns current status of the transaction.
Status
()
Status
...
...
@@ -160,17 +159,16 @@ type Transaction interface {
// Commit must not be called after transaction completion began.
Commit
(
ctx
context
.
Context
)
error
// Abort aborts the transaction.
// Abort aborts the transaction.
//
// Abort completes the transaction by executing Abort on all
// DataManagers associated with it.
//
// Abort must not be called after transaction completion began.
Abort
()
// XXX + ctx, error?
Abort
()
// XXX + ctx, error?
// XXX + Doom?
// ---- part for data managers & friends ----
// XXX move to separate interface?
...
...
@@ -208,7 +206,6 @@ func Current(ctx context.Context) Transaction {
return
currentTxn
(
ctx
)
}
// DataManager manages data and can transactionally persist it.
//
// If DataManager is registered to transaction via Transaction.Join, it will
...
...
@@ -222,12 +219,12 @@ type DataManager interface {
// if abort was caused by user requesting transaction abort. If
// two-phase commit was started and transaction needs to be aborted due
// to two-phase commit logic, TPCAbort will be called.
Abort
(
txn
Transaction
)
// XXX +ctx, error
Abort
(
txn
Transaction
)
// XXX +ctx, error
// TPCBegin should begin commit of a transaction, starting the two-phase commit.
TPCBegin
(
txn
Transaction
)
// XXX +ctx, error ?
TPCBegin
(
txn
Transaction
)
// XXX +ctx, error ?
// Commit should commit modifications to managed data.
// Commit should commit modifications to managed data.
//
// It should save changes to be made persistent if the transaction
// commits (if TPCFinish is called later). If TPCAbort is called
...
...
@@ -238,15 +235,15 @@ type DataManager interface {
// changes persist when TPCFinish is called.
Commit
(
ctx
context
.
Context
,
txn
Transaction
)
error
// TPCVote should verify that a data manager can commit the transaction.
// TPCVote should verify that a data manager can commit the transaction.
//
// This is the last chance for a data manager to vote 'no'. A data
// manager votes 'no' by returning an error.
TPCVote
(
ctx
context
.
Context
,
txn
Transaction
)
error
// TPCFinish should indicate confirmation that the transaction is done.
// TPCFinish should indicate confirmation that the transaction is done.
//
// It should make all changes to data modified by this transaction persist.
// It should make all changes to data modified by this transaction persist.
//
// This should never fail. If this returns an error, the database is
// not expected to maintain consistency; it's a serious error.
...
...
@@ -254,14 +251,13 @@ type DataManager interface {
// TPCAbort should Abort a transaction.
//
// This is called by a transaction manager to end a two-phase commit on
// This is called by a transaction manager to end a two-phase commit on
// the data manager. It should abandon all changes to data modified
// by this transaction.
//
// This should never fail.
// This should never fail.
TPCAbort
(
ctx
context
.
Context
,
txn
Transaction
)
// XXX error?
// XXX better do without SortKey - with it it is assumed that
// datamanagers are processed serially.
// SortKey() string
...
...
@@ -295,7 +291,7 @@ func With(ctx context.Context, f func(context.Context) error) (ok bool, _ error)
txn
,
ctx
:=
New
(
ctx
)
err
:=
f
(
ctx
)
if
err
!=
nil
{
txn
.
Abort
()
// XXX err
txn
.
Abort
()
// XXX err
return
false
,
err
}
...
...
go/transaction/transaction.go
View file @
485a2cfc
...
...
@@ -28,13 +28,13 @@ import (
// transaction implements Transaction.
type
transaction
struct
{
mu
sync
.
Mutex
status
Status
datav
[]
DataManager
syncv
[]
Synchronizer
mu
sync
.
Mutex
status
Status
datav
[]
DataManager
syncv
[]
Synchronizer
// metadata
user
string
user
string
description
string
extension
string
// XXX
}
...
...
@@ -137,7 +137,7 @@ func (txn *transaction) Abort() {
go
func
()
{
defer
wg
.
Done
()
datav
[
i
]
.
Abort
(
txn
)
// XXX err?
datav
[
i
]
.
Abort
(
txn
)
// XXX err?
}()
}
wg
.
Wait
()
...
...
@@ -145,7 +145,7 @@ func (txn *transaction) Abort() {
// XXX set txn status
txn
.
mu
.
Lock
()
// assert .status == Aborting
txn
.
status
=
Aborted
// XXX what if errBeforeCompletion?
txn
.
status
=
Aborted
// XXX what if errBeforeCompletion?
txn
.
mu
.
Unlock
()
// sync.AfterCompletion
...
...
@@ -192,16 +192,15 @@ func (txn *transaction) RegisterSync(sync Synchronizer) {
// must be called with .mu held.
func
(
txn
*
transaction
)
checkNotYetCompleting
(
who
string
)
{
switch
txn
.
status
{
case
Active
:
// XXX + Doomed ?
case
Active
:
// XXX + Doomed ?
// ok
default
:
panic
(
"transaction: "
+
who
+
": transaction completion already began"
)
}
}
// ---- meta ----
func
(
txn
*
transaction
)
User
()
string
{
return
txn
.
user
}
func
(
txn
*
transaction
)
Description
()
string
{
return
txn
.
description
}
func
(
txn
*
transaction
)
Extension
()
string
{
return
txn
.
extension
}
func
(
txn
*
transaction
)
User
()
string
{
return
txn
.
user
}
func
(
txn
*
transaction
)
Description
()
string
{
return
txn
.
description
}
func
(
txn
*
transaction
)
Extension
()
string
{
return
txn
.
extension
}
go/transaction/transaction_test.go
View file @
485a2cfc
...
...
@@ -44,7 +44,6 @@ func TestBasic(t *testing.T) {
Current
(
ctx
)
}()
// New
txn
,
ctx
:=
New
(
ctx
)
if
txn_
:=
Current
(
ctx
);
txn_
!=
txn
{
...
...
@@ -52,7 +51,7 @@ func TestBasic(t *testing.T) {
}
// New(!ø) -> panic
func
()
{
func
()
{
defer
func
()
{
r
:=
recover
()
if
r
==
nil
{
...
...
@@ -86,12 +85,12 @@ func (d *dmAbortOnly) Abort(txn Transaction) {
atomic
.
AddInt32
(
&
d
.
nabort
,
+
1
)
}
func
(
d
*
dmAbortOnly
)
bug
()
{
d
.
t
.
Fatal
(
"must not be called on abort"
)
}
func
(
d
*
dmAbortOnly
)
TPCBegin
(
_
Transaction
)
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
Commit
(
_
context
.
Context
,
_
Transaction
)
error
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
TPCVote
(
_
context
.
Context
,
_
Transaction
)
error
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
TPCFinish
(
_
context
.
Context
,
_
Transaction
)
error
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
TPCAbort
(
_
context
.
Context
,
_
Transaction
)
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
bug
()
{
d
.
t
.
Fatal
(
"must not be called on abort"
)
}
func
(
d
*
dmAbortOnly
)
TPCBegin
(
_
Transaction
)
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
Commit
(
_
context
.
Context
,
_
Transaction
)
error
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
TPCVote
(
_
context
.
Context
,
_
Transaction
)
error
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
TPCFinish
(
_
context
.
Context
,
_
Transaction
)
error
{
d
.
bug
();
panic
(
0
)
}
func
(
d
*
dmAbortOnly
)
TPCAbort
(
_
context
.
Context
,
_
Transaction
)
{
d
.
bug
();
panic
(
0
)
}
func
TestAbort
(
t
*
testing
.
T
)
{
txn
,
ctx
:=
New
(
context
.
Background
())
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment