精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Powerbuilder>>数据库相关技术>>[ SQL语句 ]>>关于嵌套事务和AutoCommit的一次讨论

主题:关于嵌套事务和AutoCommit的一次讨论
发信人: edison()
整理人: flyingmist(2000-03-02 14:27:06), 站内信件
    有没有人写过这样的 SQL ?( 先删除表,然后再创建表 )

String ls_sql

ls_sql = "Begin Transaction"            + ~r~n" + &
         "  Drop Table table1"          + ~r~n" + &
         "Commit Transaction"           + ~r~n" + &
         "Begin Transaction"            + ~r~n" + &
         "  Create Table table1"        + ~r~n" + &
         "  ( col1 int not null )"      + ~r~n" + &
         "Commit Transaction"
EXECUTE IMMEDIATE :ls_sql Using sqlca;

但是这样写不行,sqlca.sqlerrtext 显示要创建的表已存在!

必须要分开,这样写:
String ls_sql

// 先用一个独立的 SQL 删除表
ls_sql = "  Drop Table table1"
         
EXECUTE IMMEDIATE :is_sql Using sqlca;

// 然后才能使用 SQL 创建表
ls_sql = "  Create Table table1"        + ~r~n" + &
         "( col1 int not null )"
        
EXECUTE IMMEDIATE :is_sql Using sqlca;

按理来说这两段代码效果应该一样。但是结果就是不一样!第一段

代码就是无法完成任务,第二段就工作的很好。

但是我必须采用第一种方式,我该怎么办呢?谢谢各位!

我是 sql server 6.5

谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: ilike (自在飞花), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Thu Nov 11 19:28:31 1999), 站内信件

【 在 edison (edison) 的大作中提到: 】
:    .......
第一种写法肯定是不行的。
本身PB就有隐含的begin transaction.
对于ms sql来说,嵌套事务以第一条为准,其余无效。

你试一下前加 sqlca.autocommit=true

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.156.11]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Thu Nov 11 23:10:36 1999), 站内信件

AutoCommit = False 我试了,不行!

ilike 就是高手,虽然敲错了!

我想到第一种写法是因为我刚开始时没用加入 Begin Transaction

将删除与创建一次执行。显然这时删除表与建立表是在一个事务中。

所以我想这是不是不能成功的原因,于是采用第二中方法,结果成功了。

但是我不能用第二方法(至于为什么说不清),所以我又想出了第一种

方法,但是还是不成功!

其实我这种观点的依据是 "删除表与创建表不能在一个事务中",也不知

道这个依据是否正确(估计是错的!因为我将 AutoCommit 该成 False 

不行!)。那是什么原因呢?

这种 SQL 即使在 ISQL 执行也是一样,一样的错误(表已经存在!)。

在两条语句中加一个 GO 就没问题。但是 GO 是 isql 的关键字(或者

叫功能字),Server 语法并没有这个(在 PB 中用不了)。怎么办呢?

【 在 ilike (自在飞花) 的大作中提到: 】
: :    .......
: 你试一下前加 sqlca.autocommit=true

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: flyingmist (飘雾), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Fri Nov 12 00:18:08 1999), 站内信件

是吗?怎么我觉得autocommit 是TRUE或FALSE都没关系呢?
是这样写吗:
String ls_sql 
//sqlca.autocommit = TRUE
ls_sql = "  Drop Table TEST"          + "~r~n" + & 
         "  Create Table TEST"        + "~r~n" + & 
         "  ( col1 int not null )"
EXECUTE IMMEDIATE :ls_sql Using sqlca; 
数据库是MS Sql Server 7.0,应该和你的6.5一样吧

【 在 edison (edison) 的大作中提到: 】
: AutoCommit = False 我试了,不行!
:    .......

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.102.159.155]


发信人: rollback (true), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Fri Nov 12 01:05:37 1999), 站内信件

ilike的确是高手,autocommit=true一点都没错,不信你看看PB的help中关于Au
toCommit database preference的描述,对你的疑问有比较详细的解答。

:其实我这种观点的依据是 "删除表与创建表不能在一个事务中",也不知 
:道这个依据是否正确(估计是错的!因为我将 AutoCommit 该成 False  
:不行!)。那是什么原因呢? 

"删除表与创建表不能在一个事务中",你对这句话的理解准确无误,但是“(估
计是错的!因为我将 AutoCommit 该成 False  
不行!)”你对PB就有了误解,所以结果你还是错了,既然ilike已经提出了解决
办法,你不妨就试试嘛,举手之劳,不会有什么损失。。

【 在 edison (edison) 的大作中提到: 】
: AutoCommit = False 我试了,不行!

--
※ 修改:.rollback 于 Nov 12 01:08:17 修改本文.[FROM: 202.104.34.229]
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.34.229]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Fri Nov 12 07:35:02 1999), 站内信件

你们都搞错了, 并不是我不明白 AutoCommit = True, ilike 的意思就是让我

用 AutoCommit =  False 试一下。只是他敲错了。 am i right ilike?

是这样的,AutoCommit = True PB 就会为每条 SQL 前后加一个Begin 和 Commit

这样如果我在我的 SQL 里也加上 Begin .. 和 Commit 这就成了嵌套事务。

Sql Server 的嵌套事务是这样的:嵌套事务处理只是语法上起作用。真正作用

在数据上的 Commit 只有最后一个,也就是当 @@trancount 为 0 才真正提交

数据。所以我要将 AutoCommit 该成 False 试一下!可惜的是仍然不行。

Rollback 兄你说的 "删除表与创建表不能在一个事务中" 是对的,但是现在

为什么我已经将删除表和创建表放到两个事务中了(AutoCommit = False 的

第一种写法)还是不行?顺便能不能替我解释一下原因?我只是猜的。谢谢!

还有,各位只不知道 isql 里的那个 go 是怎么回事?会不会仅仅是一个标记

然后 isql 依据 go 将那些 sql 分成几条类似于 dynamic sql format 1 来执行。

难怪他可以解决问题,实在不行我也要学他了!谢谢各位!

【 在 rollback (true) 的大作中提到: 】
:    .......

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: flyingmist (飘雾), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Fri Nov 12 10:30:27 1999), 站内信件

我认为ilike的意思就是aotucommit=true然后把你的语句里的begin ...什
么的都不要。反正我试过是可以的,在MSSQLServer以及SQL Anywhere中都
可以。

我不明白的是你们都说删除表与创建表不能在一个事务中,为什么我试了却
可以,是不是我什么地方搞错了?看来需要恶补一下数据库理论。

【 在 edison (edison) 的大作中提到: 】
:    .......

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.102.159.155]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Fri Nov 12 11:12:09 1999), 站内信件

不会吧, 这样写?

String ls_sql
ls_sql = "Drop table a~r~n" + &
         "Create Table a ( col int )"
execute immediate :ls_sql using sqlca;

我也试了, 不行. 我最开始就是这么做的。要不然我不会一下想那么复杂。

你有没有在 isql 里运行, 这种写法在我的 isql 中都无法通过, 必须在

中间加一个 go !

太怪了!
【 在 flyingmist (飘雾) 的大作中提到: 】
:    .......

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: ilike (自在飞花), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Fri Nov 12 11:30:39 1999), 站内信件

你真是概念极度混乱,看来得好好补一补了,你就是不太明白autocommit的含义。
我说的就是autocommit=true,只有加了这句,才能执行"begin transaction"以及"com
mit rollback"等语句。
请你看一下pb help - AutoCommit database preference条目。
只有autocommit = false, PB才自动加"begin transaction".
autocommit = true,PB不加begin transaction语句,实际上此时是处于一种outside t
he scope of a transaction状态。
也就是平时isqlw的状态。
go是批结束语句,一个批中可能有几个事务也可能只有一个。
批是作用是一个批中所有语句一次发送给服务器,而不是等待前一条语句返回结果后再
发送下一句,仅此而已。
你不是有《SQL Server 6.5技术内幕》吗?那本书举了例子把批讲的很清楚。

to flyingmist:
SQL7和SQL65恰好这一点上是不一样的。
SQL7可以在trigger和存储过程中引用不存在的表等等。
你的Sybase也是不可以在同一个事务中create table和drop table的。
Autocommit选项不是对所有的数据库都有用的,比如SQLAnywhere就没有用的。
【 在 edison (edison) 的大作中提到: 】
: ......

--
※ 来源:.网易 BBS bbs.netease.com.[FROM: 202.96.156.11]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Fri Nov 12 12:54:28 1999), 站内信件

对对对,我搞糊涂了!AutoCommit = False 肯定不对。

但是按照你们三人的任何一种理论都不对:

你说 AutoCommit = True 然后第一种方法可以,但是事实不行。我的
AutoCommit 一直都是 True。

Rollback 说 "删除表与创建表不能在一个事务中"。显然我的第一种
就是将两个表放到两个事务中,但是还是不行!所以我也怀疑这个理
论。

flyingmist 要我去掉 Begin Transaction 和 Commit ,这是我首先
的做法(我肯定不会一下想到那么复杂)。也不行!但是她却行!
我败了!

所以我现在想搞清楚
1.    "删除表与创建表不能在一个事务中" 到底有没有这种事?
      还有这是为什么?
2.    Outside the scope of a transaction 是什么意思?


还有 ilike 我就是清楚 AutoCommit 的意思。这是常识,要不知道
的话我们是要被打屁股的!!

而且你表达的还有误。我觉得有必要澄清一下

看 online help 中关于 AutoCommit 的说明:
True   PowerBuilder issues SQL statements outside the scope of 
                                          ~~~~~~~
       a transaction. The statements are not part of a logical
       unit of work (LUW). If the SQL statement is successful, 
       the DBMS updates the database immediately as if a COMMIT
       statement had been issued

False  (Default) PowerBuilder issues SQL statements inside the
       scope of a transaction. PowerBuilder issues a BEGIN 
       TRANSACTION statement at the start of the connection 
       and issues another BEGIN TRANSACTION statement after 
       each COMMIT or ROLLBACK statement is issued

我们只看 False 的意思,False 的意思是 PB 在连接数据库时将会
开始一个事务( 发出一个 Begin Transaction 语句)。然后在 Commit
与 Rollback 之后将自动又发出一个 Begin Transaction 语句。

Sql Server 的 Select 会将数据加上共享锁,而且锁的释放要等到
事务结束才会释放。所以如果不将 AutoCommit 设成 True,这就出现
以前好多网友问题的为什么会死锁数据的问题,因为整个程序运行期间
处在一个事务之中,除非你 Commit 或 Rollback,但是 DW Retrieve
之后谁会去 Commit ! 其实将 AutoCommit 该成 True 所有问题都解决。

好再看 True 的意思。如果我不看 True 的解释,只看 False 的解释与
AutoCommit 的字面意思,完全可以理解成 PB 在每条 SQL 前后加了
一个事务。注意我是说每条 SQL 前后,这么理解是可以的。但是 PB 并
不是这样做,而是 DBMS 这样做了。所以 AutoCommit 并不是所有的
DBMS 都有意义。SQL SERVER 资料中的原话:SQL SERVER 默认情
况将每条 SQL 看成是独立的,并立即提交。也就是说他在每条
SQL 的前后都有一个 Begin Transaction 和 Commit Transaction。
这两句话,第一句来自<<SQL Server 6.5 技术内幕>>,第二句来自
<<Sql Server 6.5 开发指南>>。

至于对 GO 的理解我很清楚也没错,他与前端工具有关,不是 SQL 
命令。对于用 GO 分开的 SQL 将在分别使用 DB-library 的 
dbsqlexec 或 ODBC 的 SQlExecute 执行。我觉得这就是 PB 的
Dynamic sql format 1。所以我想只能采用类似于 ISQL 的写法
加一个 GO !
【 在 ilike (自在飞花) 的大作中提到: 】
: 你真是概念极度混乱,看来得好好补一补了,你就是不太明白autocommit的含义。
: ......

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: rollback (true), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Fri Nov 12 14:00:20 1999), 站内信件

唉,我和ilike都让你看同样的help,但你却只看了一半,后边还有一大段的文字
,请您耐心地看完好吗?我在这贴出一段,你看看是否有点意思。

:显然我的第一种就是将两个表放到两个事务中,但是还是不行!所以我也怀疑这个理论。
 
对于你的这个疑问,ilike在前面的贴子也有了很好的问答“对于ms sql来说,嵌
套事务以第一条为准,其余无效”
请你结合对autocommit的准确作用,和ilike说的东西再好好考虑一下也许就想通
了。

还有 "删除表与创建表不能在一个事务中"这句话完全是我引用于你上面的贴子里
的,不是我说的。

Executing SQL DDL statements   Some DBMSs require you to execute certa
in SQL statements outside the scope of a transaction. For example, whe
n connected to a SQL Server database, you must execute SQL Data Defini
tion Language (DDL) statements such as CREATE TABLE and DROP TABLE out
side a transaction. There are two reasons for this:

?It ensures that the structure of your database cannot change during a
 transaction.
?It improves database performance, because DDL statements are costly o
perations to recover.

Therefore, to execute DDL statements or stored procedures containing D
DL statements in a SQL Server database, you must set AutoCommit to Tru
e to issue the DDL statements outside the scope of a transaction. You 
should, however, set AutoCommit back to False immediately after execut
ing the DDL statements.
When you change the value of AutoCommit from False to True, PowerBuild
er or InfoMaker issues a COMMIT statement by default.
【 在 edison (edison) 的大作中提到: 】
: 对对对,我搞糊涂了!AutoCommit = False 肯定不对。
: 但是按照你们三人的任何一种理论都不对:
:    .......

--
※ 修改:.rollback 于 Nov 12 14:10:22 修改本文.[FROM: 202.104.36.238]
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.36.238]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Fri Nov 12 14:32:57 1999), 站内信件

【 在 rollback (true) 的大作中提到: 】
: 唉,我和ilike都让你看同样的help,但你却只看了一半,后边还有一大段的文字
: ,请您耐心地看完好吗?我在这贴出一段,你看看是否有点意思。

你有没有试出来? 可不可以把 Code 贴出来? 你是不是也用 sql server 6.5 ?
谢谢帮忙!

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Fri Nov 12 14:34:26 1999), 站内信件

咳,rollback 大侠,真不知道是你糊涂还是我糊涂了!!!

我不明白你什么意思。我已经强调若干次我的 AutoCommit 一直是 True 。
我以为 ilike 要我设成 false,于是我特意也将 AutoCommit 改成 False。
两种情况都不行。不知你有没有试,你试一下我发的第一个关于这个问题的
帖子里的第一个方法。注意我在用这个方法的时候 AutoCommit = True !
正是因为有问题我才过来问的。你要我看的 help 的意思就是强调
 AutoCommit 在处理 DDL 语句时应该为 True 。谢谢提示,但是你漏看了
我的帖子,我一直是 AutoCommit = True !

    还有你不是对 "删除表与创建表不能在同一个事务中" 的观点表示赞成
吗。我只是猜测的,所以我想知道到底有没有这回事,还有这是为什么?

    再有就想问一下你,你也看了你提供的 help 资料。我不理解里面的
"outside the scope of a transaction" 是什么意思。这片 help 整篇
都提到这个,我就是没搞懂这个是什么?

    还有其他几位高人,你们是什么情况使用 AutoCommit = True ?我的
所有软件只要连接 Sql Server 就将 AutoCommit 设成 True 。我觉得这
么做是正确的,否则容易引起死锁(上一篇帖子有解释)。而且 PFC 就
是提倡这么做的。我现在是被你们及位高人搞得稀里糊涂,帮忙证实一下!

谢谢,谢谢!

【 在 rollback (true) 的大作中提到: 】
: 唉,我和ilike都让你看同样的help,但你却只看了一半,后边还有一大段的文字

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: flyingmist (飘雾), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Fri Nov 12 20:00:29 1999), 站内信件

我找了个Sybase试了一下,确实不行,怎么都不行。不知道ilike是吃什么
粮食长大的,怎么什么都知道!你还是问他吧。

一般是AutoCommit=TRUE啦。不过有时会有一段SQL语句要一起提交的,就
先设成FALSE。不过我以前还真没特别注意过它,没想过死锁会跟这个有关,
看来以后要注意了。

【 在 edison (edison) 的大作中提到: 】
: 咳,rollback 大侠,真不知道是你糊涂还是我糊涂了!!!
:    .......

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.102.159.155]


发信人: rerollback (true), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Fri Nov 12 23:33:12 1999), 站内信件

这样我就闹不清了,我看你的第一方法中的确没有autocommit=true,而飘雾的回
复中却有,看来我糊涂了。
"删除表与创建表不能在一个事务中"是否正确我不敢断言,不过我在MS SQL 6.5
的isqlw中试了一下,在同一事务中也行,好象并没有这个限制。可是我知道:

“You cannot drop an object and then reference or re-create it in the 
same batch.”
“You can submit one or more batches of SQL statements to isql from an
 operating-system file. A file can include more than one batch ?more t
han one collection of SQL statements緀ach terminated by the GO end-of-
batch signal.”
我理解“EXECUTE IMMEDIATE :ls_sql Using sqlca; ”执行的实际就是sql Bat
ch,而你的第一方法中虽然有两个自定义事务但由于没有“go”所以仍属于同一
Batch中,所以会发生你所遇到的问题。

至于“outside the scope of a transaction" 的意思按字面理解就是“在事务
范围之外”,我理解help中的这句话是针对transaction object自动生成的事务
的。

对于AutoCommit = True 的使用,我是这样的:
如果不在乎Dirty read我就设AutoCommit = False还有sqlca.lock='ru',这样省
得每次更新数据时为了能控制事务的提交,而先把autocommit=false等事务完成
后后再autocommit=true。
如果在乎Dirty read,我就设AutoCommit = true还有sqlca.lock='rc'或更高级
别(这由需要定),每次更新数据时为了能控制事务的提交,先把autocommit=f
alse等事务完成后再autocommit=true。


【 在 edison (edison) 的大作中提到: 】
: 咳,rollback 大侠,真不知道是你糊涂还是我糊涂了!!!
:    .......


--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.185.234]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Sat Nov 13 10:18:52 1999), 站内信件

【 在 rerollback (true) 的大作中提到: 】
: 这样我就闹不清了,我看你的第一方法中的确没有autocommit=true,而飘雾的回
: 复中却有,看来我糊涂了。
: "删除表与创建表不能在一个事务中"是否正确我不敢断言,不过我在MS SQL 6.5
: 的isqlw中试了一下,在同一事务中也行,好象并没有这个限制。可是我知道:
: “You cannot drop an object and then reference or re-create it in the 
: same batch.”
: “You can submit one or more batches of SQL statements to isql from an
:  operating-system file. A file can include more than one batch ?more t
: han one collection of SQL statements緀ach terminated by the GO end-of-
: batch signal.”
你这段文字从哪载抄的?这里有些单词是乱码,我看不懂。可不可以告诉我或mail
我?[email protected]


: 我理解“EXECUTE IMMEDIATE :ls_sql Using sqlca; ”执行的实际就是sql Bat
: ch,而你的第一方法中虽然有两个自定义事务但由于没有“go”所以仍属于同一
: Batch中,所以会发生你所遇到的问题。

: 至于“outside the scope of a transaction" 的意思按字面理解就是“在事务
: 范围之外”,我理解help中的这句话是针对transaction object自动生成的事务
: 的。
真不好意思,你这个中文解释我也看不懂!能不能再详细一点!谢谢!

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]


发信人: rollback (true), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易虚拟社区 (Sat Nov 13 14:28:52 1999), 站内信件

那两段英文摘自MS SQL 6.5的Books online。第一段可以在transact-SQL refer
ence->B->Batches找到,第二段可以在database developer's companion->Chap
ter3 Working with data->Processing transactions in batches找到

至于“outside the scope of a transaction" 的意思按字面理解就是“在事务
范围之外”,我理解是“在任何显式的用户定义事务之外”,当autocommit=fal
se时PB的transaction object会自动产生事务(这些事务也算用户定义的显式事
务)包裹用户发往DBMS的SQL脚本。
通俗点说就是在SQL不被begin tran和commit tran所包裹。这样要求的原因是基
MS SQL 6.5对嵌套事务的处理方法。

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.34.43]


发信人: edison (edison), 信区: Powerbuilder
标  题: Re: 江湖救急1
发信站: 网易 BBS (Sat Nov 13 15:44:01 1999), 站内信件

多谢,多谢,我再仔细揣摩揣摩!

--
谢谢没有在 "将本文章寄一份给原作者" 处打勾, 再次感谢!

※ 来源:.网易 BBS bbs.netease.com.[FROM: bbs.szptt.net.cn]

[关闭][返回]