第二十八章 Caché 命令大全 TSTART 命令
第二十八章 Caché 命令大全 TSTART 命令
重点
- 为嵌套事务发出
TROLLBACK 1
将回滚在该嵌套事务中所做的更改,并递减$TLEVEL
。无论发出了多少级别的TSTART
,都可以发出TROLLBACK
来回滚整个事务。 - 发出T
START
会递增$TLEVEL
值 - 嵌套事务期间所做的更改仅在提交最外面的事务时才不可逆转地提交;也就是说,当
TCOMMIT
将$TLEVEL
值递减为0时。 - 嵌套事务的最大层数为255。
大纲
TSTART:pc
TS:pc
参数
- pc 可选 - 后置表达式
描述
TSTART
标记事务的开始。在TSTART
之后,记录数据库操作以启用后续的TCOMMIT
或TROLLBACK
命令。
TSTART
递增$TLEVEL
特殊变量的值。$TLEVEL
值为0表示没有有效的事务。第一个TSTART
开始一个事务,并将$TLEVEL
递增到1。后续TSTART
命令可以创建嵌套事务,从而进一步递增$TLEVEL
。
并非事务内发生的所有操作都可以回滚。例如,在事务内设置全局变量可以回滚;在事务内设置局部变量不能回滚。
默认情况下,事务内发布的锁将一直保持到事务结束,即使该锁在事务内释放也是如此。设置锁定时可以覆盖此默认值。
嵌套事务
如果在事务内发出TSTART
,它将开始嵌套事务。发出TSTART
会递增$TLEVEL
值,指示事务嵌套的层数。可以通过发出TCOMMIT
提交嵌套事务或发出TRolback1
回滚嵌套事务来结束嵌套事务。结束嵌套事务会使$TLEVEL
值递减1。
- 为嵌套事务发出
TROLLBACK 1
将回滚在该嵌套事务中所做的更改,并递减$TLEVEL
。无论发出了多少级别的TSTART
,都可以发出TROLLBACK
来回滚整个事务。 - 为嵌套事务发出
TCOMMIT
会使$TLEVEL
递减,但嵌套事务的实际提交会延迟。嵌套事务期间所做的更改仅在提交最外面的事务时才不可逆转地提交;也就是说,当TCOMMIT
将$TLEVEL
值递减为0时。
可以使用%SYS.Journal.System
类的GetImageJournalInfo()
方法在日志文件中搜索TSTART
命令,从而识别打开的事务。如果$TLEVEL
为零,则TSTART
写入“BT”(BEGIN TRANSACTION)
日志文件记录,如果$TLEVEL
大于0,则写入“BTL”(BEGIN TRANSACTION WITH LEVEL)
日志文件记录。
嵌套事务的最大层数为255。尝试超过此嵌套级别限制会导致<Transaction Level>
错误。
SQL Transactions
CachéObjectScript和SQL TRANSACTION
命令完全兼容且可互换,但有以下例外:如果没有当前事务,ObjectScript TSTART
和SQL START TRANSACTION
都会启动事务。但是,START TRANSACTION
不支持嵌套事务。因此,如果需要(或可能需要)嵌套事务,最好使用TSTART
启动事务。如果需要与SQL标准兼容,请使用START TRANSACTION
。
CachéObjectScript事务处理为嵌套事务提供有限的支持。SQL事务处理为事务内的保存点提供支持。
参数
pc
可选的后置条件表达式。如果后置条件表达式为TRUE,则Caché执行TSTART
命令;如果后置条件表达式为FALSE,则Caché不执行TSTART命令。
示例
下面的示例使用单级事务将随机金额的资金从一个帐户转移到另一个帐户。如果转帐金额大于可用余额,程序将回退事务处理:
/// d ##class(PHA.TEST.Command).TestBankAccounts()
ClassMethod TestBankAccounts()
{
SetupBankAccounts
SET num=12345
SET ^CHECKING(num,"balance")=500.99
SET ^SAVINGS(num,"balance")=100.22
IF $DATA(^NumberOfTransfers)=0 {
SET ^NumberOfTransfers=0
}
BankTransfer
WRITE "转移之前:",!,"Checking=$",^CHECKING(num,"balance")," Savings=$",^SAVINGS(num,"balance"),!
// 将资金从一个账户转到另一个账户
SET transfer=$RANDOM(1000)
WRITE "转账金额 $",transfer,!
DO CkToSav(num,transfer)
IF ok=1 {
WRITE "成功转移",!,"迄今为止的转账次数=",^NumberOfTransfers,!
} ELSE {
WRITE "*** 资金不足 ***",!
}
WRITE "转移之后:",!,"Checking=$",^CHECKING(num,"balance")," Savings=$",^SAVINGS(num,"balance"),!
RETURN
CkToSav(acct,amt)
TSTART
SET ^CHECKING(acct,"balance") = ^CHECKING(acct,"balance") - amt
SET ^SAVINGS(acct,"balance") = ^SAVINGS(acct,"balance") + amt
SET ^NumberOfTransfers=^NumberOfTransfers + 1
IF ^CHECKING(acct,"balance") > 0 {
TCOMMIT SET ok=1 QUIT:ok
}
ELSE {
TROLLBACK SET ok=0 QUIT:ok
}
}
DHC-APP>d ##class(PHA.TEST.Command).TestBankAccounts()
转移之前:
Checking=$500.99 Savings=$100.22
转账金额 $669
*** 资金不足 ***
转移之后:
Checking=$500.99 Savings=$100.22
DHC-APP>d ##class(PHA.TEST.Command).TestBankAccounts()
转移之前:
Checking=$500.99 Savings=$100.22
转账金额 $84
成功转移
迄今为止的转账次数=5
转移之后:
Checking=$416.99 Savings=$184.22
以下示例使用TSTART
创建嵌套事务。它们显示了三种回滚嵌套事务的方案:
回滚最里面的事务,提交中间事务,提交最外面的事务:
/// d ##class(PHA.TEST.Command).TestTstart()
ClassMethod TestTstart()
{
KILL ^a,^b,^c
TSTART SET ^a=1 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^b=2 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^c=3 WRITE "tlevel=",$TLEVEL,!
TROLLBACK 1 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
IF $DATA(^a) {WRITE "^a=",^a,!} ELSE {WRITE "^a is undefined",!}
IF $DATA(^b) {WRITE "^b=",^b,!} ELSE {WRITE "^b is undefined",!}
IF $DATA(^c) {WRITE "^c=",^c,!} ELSE {WRITE "^c is undefined",!}
}
DHC-APP>d ##class(PHA.TEST.Command).TestTstart()
tlevel=1
tlevel=2
tlevel=3
tlevel=2
tlevel=1
tlevel=0
^a=1
^b=2
^c is undefined
提交最里面的事务,回滚中间的事务,提交最外面的事务:
/// d ##class(PHA.TEST.Command).TestTstart1()
ClassMethod TestTstart1()
{
KILL ^a,^b,^c
TSTART SET ^a=1 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^b=2 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^c=3 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TROLLBACK 1 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
IF $DATA(^a) {WRITE "^a=",^a,!} ELSE {WRITE "^a is undefined",!}
IF $DATA(^b) {WRITE "^b=",^b,!} ELSE {WRITE "^b is undefined",!}
IF $DATA(^c) {WRITE "^c=",^c,!} ELSE {WRITE "^c is undefined",!}
}
DHC-APP>d ##class(PHA.TEST.Command).TestTstart1()
tlevel=1
tlevel=2
tlevel=3
tlevel=2
tlevel=1
tlevel=0
^a=1
^b is undefined
^c is undefined
提交最里面的事务,提交中间的事务,回滚最外面的事务:
/// d ##class(PHA.TEST.Command).TestTstart2()
ClassMethod TestTstart2()
{
KILL ^a,^b,^c
TSTART SET ^a=1 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^b=2 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^c=3 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TROLLBACK 1 WRITE "tlevel=",$TLEVEL,!
IF $DATA(^a) {WRITE "^a=",^a,!} ELSE {WRITE "^a is undefined",!}
IF $DATA(^b) {WRITE "^b=",^b,!} ELSE {WRITE "^b is undefined",!}
IF $DATA(^c) {WRITE "^c=",^c,!} ELSE {WRITE "^c is undefined",!}
}
DHC-APP>d ##class(PHA.TEST.Command).TestTstart2()
tlevel=1
tlevel=2
tlevel=3
tlevel=2
tlevel=1
tlevel=0
^a is undefined
^b is undefined
^c is undefined
请注意,在第三种情况下,TROLLBACK 1
和TROLLBACK
将具有相同的结果,因为两者都会将$ TLEVEL
减为0。
本文地址:https://blog.csdn.net/yaoxin521123/article/details/107627702
上一篇: 锤爆mysql之索引
下一篇: 从昆山宝马男砍人事件中
推荐阅读
-
第二十八章 Caché 命令大全 TSTART 命令
-
第四十五章 Caché 命令大全 ZSAVE 命令
-
《Linux命令行与shell脚本编程大全》 第二十二章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十四章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十五章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十六章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十七章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十七章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十六章 学习笔记
-
《Linux命令行与shell脚本编程大全》 第二十五章 学习笔记