Skip to content

Added Isolation concept #1739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions internal/query/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func begin(
response, err := client.BeginTransaction(ctx,
&Ydb_Query.BeginTransactionRequest{
SessionId: sessionID,
TxSettings: txSettings.ToYdbQuerySettings(),
TxSettings: txSettings.ToQuerySettings(),
},
)
if err != nil {
Expand Down Expand Up @@ -185,7 +185,7 @@ func (tx *Transaction) txControl() *baseTx.Control {
}

return baseTx.NewControl(
baseTx.BeginTx(tx.txSettings...),
tx.txSettings,
)
}

Expand Down
74 changes: 74 additions & 0 deletions internal/tx/isolation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package tx

import (
"fmt"

"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Query"
"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Table"
)

type Isolation int

func (iso Isolation) ToTableSettings() *Ydb_Table.TransactionSettings {
return iso.tableTxSelector().BeginTx
}

func (iso Isolation) ToQuerySettings() *Ydb_Query.TransactionSettings {
return iso.queryTxSelector().BeginTx
}

func (iso Isolation) applyQueryTxSelector(txControl *Ydb_Query.TransactionControl) {
txControl.TxSelector = iso.queryTxSelector()
}

func (iso Isolation) applyTableTxSelector(txControl *Ydb_Table.TransactionControl) {
txControl.TxSelector = iso.tableTxSelector()
}

func (iso Isolation) applyTxControlOption(txControl *Control) {
txControl.selector = iso
}

func (iso Isolation) tableTxSelector() *Ydb_Table.TransactionControl_BeginTx {
switch iso {
case SerializableRW:
return tableSerializableReadWriteTxSelector
case SnapshotRO:
return tableSnapshotReadOnlyTxSelector
case OnlineRO:
return tableOnlineReadOnlyForbidInconsistentReadsTxSelector
case OnlineROWithInconsistentReads:
return tableOnlineReadOnlyAllowInconsistentReadsTxSelector
case StaleRO:
return tableStaleReadOnlyTxSelector
default:
panic(fmt.Sprintf("unknown isolation: %d", iso))
}
}

func (iso Isolation) queryTxSelector() *Ydb_Query.TransactionControl_BeginTx {
switch iso {
case SerializableRW:
return querySerializableReadWriteTxSelector
case SnapshotRO:
return querySnapshotReadOnlyTxSelector
case OnlineRO:
return queryOnlineReadOnlyForbidInconsistentReadsTxSelector
case OnlineROWithInconsistentReads:
return queryOnlineReadOnlyAllowInconsistentReadsTxSelector
case StaleRO:
return queryStaleReadOnlyTxSelector
default:
panic(fmt.Sprintf("unknown isolation: %d", iso))
Comment on lines +32 to +62
Copy link
Preview

Copilot AI May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider handling unexpected isolation values more gracefully instead of panicking, such as by returning an error, to improve robustness in production environments.

Suggested change
func (iso Isolation) tableTxSelector() *Ydb_Table.TransactionControl_BeginTx {
switch iso {
case SerializableRW:
return tableSerializableReadWriteTxSelector
case SnapshotRO:
return tableSnapshotReadOnlyTxSelector
case OnlineRO:
return tableOnlineReadOnlyForbidInconsistentReadsTxSelector
case OnlineROWithInconsistentReads:
return tableOnlineReadOnlyAllowInconsistentReadsTxSelector
case StaleRO:
return tableStaleReadOnlyTxSelector
default:
panic(fmt.Sprintf("unknown isolation: %d", iso))
}
}
func (iso Isolation) queryTxSelector() *Ydb_Query.TransactionControl_BeginTx {
switch iso {
case SerializableRW:
return querySerializableReadWriteTxSelector
case SnapshotRO:
return querySnapshotReadOnlyTxSelector
case OnlineRO:
return queryOnlineReadOnlyForbidInconsistentReadsTxSelector
case OnlineROWithInconsistentReads:
return queryOnlineReadOnlyAllowInconsistentReadsTxSelector
case StaleRO:
return queryStaleReadOnlyTxSelector
default:
panic(fmt.Sprintf("unknown isolation: %d", iso))
func (iso Isolation) tableTxSelector() (*Ydb_Table.TransactionControl_BeginTx, error) {
switch iso {
case SerializableRW:
return tableSerializableReadWriteTxSelector, nil
case SnapshotRO:
return tableSnapshotReadOnlyTxSelector, nil
case OnlineRO:
return tableOnlineReadOnlyForbidInconsistentReadsTxSelector, nil
case OnlineROWithInconsistentReads:
return tableOnlineReadOnlyAllowInconsistentReadsTxSelector, nil
case StaleRO:
return tableStaleReadOnlyTxSelector, nil
default:
return nil, fmt.Errorf("unknown isolation: %d", iso)
}
}
func (iso Isolation) queryTxSelector() (*Ydb_Query.TransactionControl_BeginTx, error) {
switch iso {
case SerializableRW:
return querySerializableReadWriteTxSelector, nil
case SnapshotRO:
return querySnapshotReadOnlyTxSelector, nil
case OnlineRO:
return queryOnlineReadOnlyForbidInconsistentReadsTxSelector, nil
case OnlineROWithInconsistentReads:
return queryOnlineReadOnlyAllowInconsistentReadsTxSelector, nil
case StaleRO:
return queryStaleReadOnlyTxSelector, nil
default:
return nil, fmt.Errorf("unknown isolation: %d", iso)

Copilot uses AI. Check for mistakes.

}
}

const (
SerializableRW = Isolation(iota)
SnapshotRO
OnlineRO
OnlineROWithInconsistentReads
StaleRO
)

var _ Settings = Isolation(0)
97 changes: 91 additions & 6 deletions internal/tx/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,83 @@ var (
querySerializableReadWrite = &Ydb_Query.TransactionSettings_SerializableReadWrite{
SerializableReadWrite: &Ydb_Query.SerializableModeSettings{},
}
querySerializableReadWriteTxSelector = &Ydb_Query.TransactionControl_BeginTx{
BeginTx: &Ydb_Query.TransactionSettings{
TxMode: querySerializableReadWrite,
},
}
queryStaleReadOnly = &Ydb_Query.TransactionSettings_StaleReadOnly{
StaleReadOnly: &Ydb_Query.StaleModeSettings{},
}
queryStaleReadOnlyTxSelector = &Ydb_Query.TransactionControl_BeginTx{
BeginTx: &Ydb_Query.TransactionSettings{
TxMode: queryStaleReadOnly,
},
}
querySnapshotReadOnly = &Ydb_Query.TransactionSettings_SnapshotReadOnly{
SnapshotReadOnly: &Ydb_Query.SnapshotModeSettings{},
}
querySnapshotReadOnlyTxSelector = &Ydb_Query.TransactionControl_BeginTx{
BeginTx: &Ydb_Query.TransactionSettings{
TxMode: querySnapshotReadOnly,
},
}
queryOnlineReadOnlyAllowInconsistentReads = &Ydb_Query.TransactionSettings_OnlineReadOnly{
OnlineReadOnly: &Ydb_Query.OnlineModeSettings{AllowInconsistentReads: true},
}
queryOnlineReadOnlyAllowInconsistentReadsTxSelector = &Ydb_Query.TransactionControl_BeginTx{
BeginTx: &Ydb_Query.TransactionSettings{
TxMode: queryOnlineReadOnlyAllowInconsistentReads,
},
}
queryOnlineReadOnlyForbidInconsistentReads = &Ydb_Query.TransactionSettings_OnlineReadOnly{
OnlineReadOnly: &Ydb_Query.OnlineModeSettings{AllowInconsistentReads: false},
}
queryOnlineReadOnlyForbidInconsistentReadsTxSelector = &Ydb_Query.TransactionControl_BeginTx{
BeginTx: &Ydb_Query.TransactionSettings{
TxMode: queryOnlineReadOnlyForbidInconsistentReads,
},
}
tableSerializableReadWrite = &Ydb_Table.TransactionSettings_SerializableReadWrite{
SerializableReadWrite: &Ydb_Table.SerializableModeSettings{},
}
tableSerializableReadWriteTxSelector = &Ydb_Table.TransactionControl_BeginTx{
BeginTx: &Ydb_Table.TransactionSettings{
TxMode: tableSerializableReadWrite,
},
}
tableStaleReadOnly = &Ydb_Table.TransactionSettings_StaleReadOnly{
StaleReadOnly: &Ydb_Table.StaleModeSettings{},
}
tableStaleReadOnlyTxSelector = &Ydb_Table.TransactionControl_BeginTx{
BeginTx: &Ydb_Table.TransactionSettings{
TxMode: tableStaleReadOnly,
},
}
tableSnapshotReadOnly = &Ydb_Table.TransactionSettings_SnapshotReadOnly{
SnapshotReadOnly: &Ydb_Table.SnapshotModeSettings{},
}
tableSnapshotReadOnlyTxSelector = &Ydb_Table.TransactionControl_BeginTx{
BeginTx: &Ydb_Table.TransactionSettings{
TxMode: tableSnapshotReadOnly,
},
}
tableOnlineReadOnlyAllowInconsistentReads = &Ydb_Table.TransactionSettings_OnlineReadOnly{
OnlineReadOnly: &Ydb_Table.OnlineModeSettings{AllowInconsistentReads: true},
}
tableOnlineReadOnlyAllowInconsistentReadsTxSelector = &Ydb_Table.TransactionControl_BeginTx{
BeginTx: &Ydb_Table.TransactionSettings{
TxMode: tableOnlineReadOnlyAllowInconsistentReads,
},
}
tableOnlineReadOnlyForbidInconsistentReads = &Ydb_Table.TransactionSettings_OnlineReadOnly{
OnlineReadOnly: &Ydb_Table.OnlineModeSettings{AllowInconsistentReads: false},
}
tableOnlineReadOnlyForbidInconsistentReadsTxSelector = &Ydb_Table.TransactionControl_BeginTx{
BeginTx: &Ydb_Table.TransactionSettings{
TxMode: tableOnlineReadOnlyForbidInconsistentReads,
},
}
)

// Transaction settings options
Expand All @@ -44,10 +94,45 @@ type (
ApplyQueryTxSettingsOption(txSettings *Ydb_Query.TransactionSettings)
ApplyTableTxSettingsOption(txSettings *Ydb_Table.TransactionSettings)
}
Settings []SettingsOption
Settings interface {
ControlOption
Selector

ToTableSettings() *Ydb_Table.TransactionSettings
ToQuerySettings() *Ydb_Query.TransactionSettings
}
Options []SettingsOption
)

func (opts Settings) applyTableTxSelector(txControl *Ydb_Table.TransactionControl) {
func (opts Options) applyTxControlOption(txControl *Control) {
txControl.selector = BeginTx(opts...)
}

func (opts Options) ToTableSettings() *Ydb_Table.TransactionSettings {
txSettings := &Ydb_Table.TransactionSettings{}
for _, opt := range opts {
if opt != nil {
opt.ApplyTableTxSettingsOption(txSettings)
}
}

return txSettings
}

func (opts Options) ToQuerySettings() *Ydb_Query.TransactionSettings {
txSettings := &Ydb_Query.TransactionSettings{}
for _, opt := range opts {
if opt != nil {
opt.ApplyQueryTxSettingsOption(txSettings)
}
}

return txSettings
}

var _ Settings = Options(nil)

func (opts Options) applyTableTxSelector(txControl *Ydb_Table.TransactionControl) {
beginTx := &Ydb_Table.TransactionControl_BeginTx{
BeginTx: &Ydb_Table.TransactionSettings{},
}
Expand All @@ -59,7 +144,7 @@ func (opts Settings) applyTableTxSelector(txControl *Ydb_Table.TransactionContro
txControl.TxSelector = beginTx
}

func (opts Settings) applyQueryTxSelector(txControl *Ydb_Query.TransactionControl) {
func (opts Options) applyQueryTxSelector(txControl *Ydb_Query.TransactionControl) {
beginTx := &Ydb_Query.TransactionControl_BeginTx{
BeginTx: &Ydb_Query.TransactionSettings{},
}
Expand All @@ -71,7 +156,7 @@ func (opts Settings) applyQueryTxSelector(txControl *Ydb_Query.TransactionContro
txControl.TxSelector = beginTx
}

func (opts Settings) ToYdbQuerySettings() *Ydb_Query.TransactionSettings {
func (opts Options) ToYdbQuerySettings() *Ydb_Query.TransactionSettings {
txSettings := &Ydb_Query.TransactionSettings{}
for _, opt := range opts {
if opt != nil {
Expand All @@ -82,7 +167,7 @@ func (opts Settings) ToYdbQuerySettings() *Ydb_Query.TransactionSettings {
return txSettings
}

func (opts Settings) ToYdbTableSettings() *Ydb_Table.TransactionSettings {
func (opts Options) ToYdbTableSettings() *Ydb_Table.TransactionSettings {
txSettings := &Ydb_Table.TransactionSettings{}
for _, opt := range opts {
if opt != nil {
Expand All @@ -94,7 +179,7 @@ func (opts Settings) ToYdbTableSettings() *Ydb_Table.TransactionSettings {
}

// NewSettings returns transaction settings
func NewSettings(opts ...SettingsOption) Settings {
func NewSettings(opts ...SettingsOption) Options {
Comment on lines 181 to +182
Copy link
Preview

Copilot AI May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider renaming NewSettings to NewOptions to better align with the new Options type, or update documentation to clarify the transition from Settings to Options.

Copilot uses AI. Check for mistakes.

return opts
}

Expand Down
22 changes: 20 additions & 2 deletions query/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,27 @@ type (
CommitTx(ctx context.Context) (err error)
Rollback(ctx context.Context) (err error)
}
TransactionControl = tx.Control

// TransactionControl is a special YDB object for define how to start (TransactionSettings) and end (CommitTx flag)
// of transaction per each query
// Deprecated: doesn't exists any use cases, when CommitTx=false
TransactionControl = tx.Control

TransactionSettings = tx.Settings
TransactionOption = tx.SettingsOption

// Isolation is well-known definition about isolation concurrent transactions
// The closest concept of isolation in ydb is transaction settings.
// Almost TransactionSettings matches to standard isolation levels (excluding OnlineReadOnly)
Isolation = tx.Settings
)

const (
SerializableRW = tx.SerializableRW
SnapshotRO = tx.SnapshotRO
OnlineRO = tx.OnlineRO
OnlineROWithInconsistentReads = tx.OnlineROWithInconsistentReads
StaleRO = tx.StaleRO
)

// BeginTx returns selector transaction control option
Expand Down Expand Up @@ -96,7 +114,7 @@ func SnapshotReadOnlyTxControl() *TransactionControl {

// TxSettings returns transaction settings
func TxSettings(opts ...tx.SettingsOption) TransactionSettings {
return opts
return tx.NewSettings(opts...)
}

func WithDefaultTxMode() TransactionOption {
Expand Down
2 changes: 1 addition & 1 deletion table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ type Session interface {
}

type (
TransactionSettings = tx.Settings
TransactionSettings = tx.Options
// Transaction control options
Copy link
Preview

Copilot AI May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that any related documentation or inline comments are updated to reflect the change from tx.Settings to tx.Options.

Suggested change
// Transaction control options
// TransactionSettings is an alias for tx.Options (previously tx.Settings) used for transaction control options.

Copilot uses AI. Check for mistakes.

TxOption = tx.SettingsOption
)
Expand Down
Loading