一条SQL语句是不是默认为一个事务

ding1989218 2009-04-07 11:44:13
比如:

select *
from table1
where exists(select *from table1);

这一条语句两次select *from table1
如果一条语句默认为是一个事务的话,就可以保证两次selet *from table1是相同的结果,否则,就不一定,这样的话会出现难以预料的后果;
所以确认一下,一条SQL语句是不是默认为一个事务?
...全文
2029 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
oO寒枫Oo 2010-06-24
  • 打赏
  • 举报
回复
先看看事务的定义 额~~
bobo_msdn 2010-06-24
  • 打赏
  • 举报
回复
受教!!
threeYUAN 2009-11-05
  • 打赏
  • 举报
回复
真是没遇到过这种问题
dengxingbo 2009-11-05
  • 打赏
  • 举报
回复
自动提交事务---数据库引擎的默认模式。每个单独的 Transact-SQL 语句都在其完成后提交。不必指定任何语句来控制事务。
所以说应该是每一个SQL数据库都当做一个事物处理,但是你也可以把事务的控制交给程序,这要通过显式事务来完成.
keleziwei 2009-05-10
  • 打赏
  • 举报
回复
这个问题值得学习。关注。。
用心呼吸 2009-05-09
  • 打赏
  • 举报
回复
事务(数据库引擎)

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性和持久性 (ACID) 属性,只有这样才能成为一个事务。原子性事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

一致性

事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。

隔离

由并发事务所作的修改必须与任何其他并发事务所作的修改隔离。事务识别数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是第二个事务修改它之后的状态,事务不会识别中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。

持久性

事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。



企业数据库系统(如数据库引擎 实例)有责任提供一种机制,保证每个事务的物理完整性。数据库引擎提供:

锁定设备,使事务保持隔离。

记录设备,保证事务的持久性。即使服务器硬件、操作系统或数据库引擎 实例自身出现故障,该实例也可以在重新启动时使用事务日志,将所有未完成的事务自动地回滚到系统出现故障的点。事务管理特性,强制保持事务的原子性和一致性。事务启动之后,就必须成功完成,否则数据库引擎 实例将撤消该事务启动之后对数据所做的所有修改事务是单个的工作单元。如果某一事务成功,则在该事务中进行的所有数据修改均会提交,成为数据库中的永久组成部分。如果事务遇到错误且必须取消或回滚,则所有数据修改均被清除。



SQL Server 以下列事务模式运行。

自动提交事务
每条单独的语句都是一个事务。

显式事务
每个事务均以 BEGIN TRANSACTION 语句显式开始,以 COMMIT 或 ROLLBACK 语句显式结束。

隐式事务
在前一个事务完成时新事务隐式启动,但每个事务仍以 COMMIT 或 ROLLBACK 语句显式完成。

批处理级事务只能应用于多个活动结果集 (MARS),在 MARS 会话中启动的 Transact-SQL 显式或隐式事务变为批处理级事务。当批处理完成时没有提交或回滚的批处理级事务自动由 SQL Server 进行回滚。


事务并发处理会产生的问题

  丢失更新

  当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题、 每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。

  脏读

  当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。

  不可重复读

  当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析与未确认的相关性类似,因为其它事

务也是正在更改第二个事务正在读取的数据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。

  幻像读

  当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。


事物的一个典型例子
银行业务。事务处理应当包括从一个帐户到另一帐户的转帐过程。这一过程属于事务处理,原因是从某帐户中支出和在另一帐户存入两个动作,必须被作为一个整体来执行——任何一方都不允许失败。在深入研究ADO.NET编程之前,让我们先来看看在SQL中是如何进行事务处理的。

SQL事务处理
SQL允许开发人员使用两个简单的声明来使用事务处理

Begin Transaction (启动事务处理)

Commit Transaction (提交事务处理)

在两条声明中的所有语句都成为事务处理的一部分。命令Begin Transaction位于整个事务处理的起始位置,因此其后的所有命令只有在执行到

命令Commit Transaction时才会被一并执行。ADO.NET方法就这么简单。
ADO.NET事务处理
事务处理需要一个数据库连接以及一个事务处理对象。在SQL Server和ADO.NET中使用事务处理的难点在于SqlTransaction类。此类名称随所使

用的数据库平台的不同而会有一些变化。例如,对于OLEDB数据库来说,事务处理类名为OleDbTransaction。

System.Data.SqlClient namespace包括了SqlTransaction类。此类包括了两个属性:

Connection:指示同事务处理相关联的SqlConnection对象;

IsolationLevel:定义事务处理的IsolationLevel。

属性IsolationLevel是包括如下成员的枚举对象:

Chaos:从高度独立的事务处理中出现的pending changes不能被覆盖;

ReadCommitted:当数据需要被非恶意读取时,采用共享锁定(shared locks),但数据仍然可以在事务处理结束时被更新,这造成了非重复性

的数据读取(nonrepeatable reads)或phantom data的产生;

ReadUncommitted:恶意读取数据是可能发生的,这表示没有使用共享锁定(shared locks),并且没有实现独占锁定(exclusive locks);

RepeatableRead:锁定查询中所用到的所有数据,由此避免其他用户对数据进行更新。在phantom rows仍然可用的状态下,这可以避免非重复

性的数据读取(nonrepeatable reads);

Serialisable:在DataSet中进行范围锁定,由此防止其他用户在事务处理结束之前更新数据或在数据库中插入行;

IsolationLevel定义锁定记录的级别,但这一概念不在本文论述范围之内。对象SqlTransaction也提供了类似的方法。你可以使用以下方法来

进行事务处理:

Commit:提交数据库事务处理;

Rollback:从未决状态(pending state)反转(roll back)事务处理。事务处理一旦被提交后即不能执行此操作;

Save:在事务处理中创建savepoint可以对事务处理的一部分进行反转,并且指定savepoint名称。
JonasFeng 2009-05-09
  • 打赏
  • 举报
回复
select *
from table1
where exists(select *from table1);
是一条SQL语句。


SELECT 不是事务。
xiahaook12345 2009-05-08
  • 打赏
  • 举报
回复
学习
firefly_2008 2009-05-08
  • 打赏
  • 举报
回复
學習了。。。
jiatongtong 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用楼主 ding1989218 的帖子:]
比如:

select *
from table1
where exists(select *from table1);

这一条语句两次select *from table1
如果一条语句默认为是一个事务的话,就可以保证两次selet *from table1是相同的结果,否则,就不一定,这样的话会出现难以预料的后果;
所以确认一下,一条SQL语句是不是默认为一个事务?
[/Quote]

sql中关于事务的加锁类型有两种:共享锁,独占锁
共享锁:可以从相关的表中读出数据,但是不可以向相关表中修改(包括插入,删除等等操作...)
独占锁:就是完全占有,不提交是不允许对表做任何操作,包括读出,写入等.

其实每个select语句默认开启的是一个共享锁的事务类型,因为有了共享锁机制的保证,所以不用担心期间数据变动问题.
yesyesyes 2009-04-08
  • 打赏
  • 举报
回复
联机丛书中的

事务
事务是单个的工作单元。如果某一事务成功,则在该事务中进行的所有数据更改均会提交,成为数据库中的永久组成部分。如果事务遇到错误且必须取消或回滚,则所有数据更改均被清除。

Microsoft® SQL Server™ 以三种事务模式运行:

自动提交事务

每条单独的语句都是一个事务。

显式事务

每个事务均以 BEGIN TRANSACTION 语句显式开始,以 COMMIT 或 ROLLBACK 语句显式结束。

隐性事务

在前一个事务完成时新事务隐式启动,但每个事务仍以 COMMIT 或 ROLLBACK 语句显式完成。

  • 打赏
  • 举报
回复
[Quote=引用楼主 ding1989218 的帖子:]
比如:

select *
from table1
where exists(select *from table1);

这一条语句两次select *from table1
如果一条语句默认为是一个事务的话,就可以保证两次selet *from table1是相同的结果,否则,就不一定,这样的话会出现难以预料的后果;
所以确认一下,一条SQL语句是不是默认为一个事务?
[/Quote]

1、select *
from table1
where exists(select *from table1); 这个应该是一个语句,而不是两个语句。
2、你可以试试
update tb set
where exists(select *from table1 with(xlock)); 如果update和select是两个语句的话,那么update是没办法执行的。因为select会对表加共享锁(在这里强制加了x锁),那么update是需要加另一个X锁的,那么这样就会造成死锁,而这条语句是没办法执行的。
事实是这条语句可以执行,所以update……select这是一条语句,一次类推你的也是一条语句。所以这个语句是一个事物。
3、如果对一个表加了共享锁,那么还是可以对表再加共享锁的,也就是即使你对一个表进行select,那么同时也可以执行另一个select,不会出现你所说的难以预料的结果
jwdream2008 2009-04-08
  • 打赏
  • 举报
回复
学习了了!
liujt09 2009-04-08
  • 打赏
  • 举报
回复
没错
zhnzzy 2009-04-08
  • 打赏
  • 举报
回复
你这还是一条语句,而一条语句是可以默认做一个事务
ding1989218 2009-04-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sdhdy 的回复:]
引用楼主 ding1989218 的帖子:
比如:

select *
from table1
where exists(select *from table1);

这一条语句两次select *from table1
如果一条语句默认为是一个事务的话,就可以保证两次selet *from table1是相同的结果,否则,就不一定,这样的话会出现难以预料的后果;
所以确认一下,一条SQL语句是不是默认为一个事务?


你的语句的意思:只要table1里面有记录,就显示table1的内容。
[/Quote]

这个语句是临时构造的,比如说如此呢:
select firstcolumn
from table1
where fristcolumn in (select firstcolumn from table1);

如果在第二个select firstcolumn from table1的时候得出三个值{1,2,3}
可是在第一个select first column的时候(假设不是一条语句不是事务),可能因为另一些语句导致变为{1,2},则最终结果是{1,2},显然与程序员本意不符,我想要得到确切的说明:一条语句是不是事务?
sdhdy 2009-04-07
  • 打赏
  • 举报
回复
一条语句默认为一个事务,这倒没听说。
sdhdy 2009-04-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 ding1989218 的帖子:]
比如:

select *
from table1
where exists(select *from table1);

这一条语句两次select *from table1
如果一条语句默认为是一个事务的话,就可以保证两次selet *from table1是相同的结果,否则,就不一定,这样的话会出现难以预料的后果;
所以确认一下,一条SQL语句是不是默认为一个事务?
[/Quote]

你的语句的意思:只要table1里面有记录,就显示table1的内容。
ding1989218 2009-04-07
  • 打赏
  • 举报
回复
有什么证据吗?
另外,在sql server 中能够由程序员来控制锁的粒度吗?
比如说,有时只是想要锁元组
ding1989218 2009-04-07
  • 打赏
  • 举报
回复
能不能给点事例证明一下,或者指出验证的方法?

另外,能不能自己控制锁的粒度以提高效率?
加载更多回复(13)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧