多条select查询语句 为保一致性 加事务有用吗
时间:2011-12-08
来源:互联网
事务嘛 就是保持数据的一致性
一般都是用在插入更新删除上 我不太清楚在查询上是否有用
请教下大家
当然不光光全是查询 比如取最大值然后插入 这个时候是不是应该在 查询(select)最大值和插入这个最大值(insert)加入事务呢?
问题2
最后想问下 比如程序中一个取值sql语句开启一个事务 还没有释放的时候 假如又有人来取值 应该是会等待事务释放才能取是吧, 我就想问 这个事务它是怎么知道我要等的就是这个取值sql 就是说怎么知道我上一次的事务没释放呢??
作者: chopper7278 发布时间: 2011-12-08
----原子性测试--- --表t1,id只能等于1 create table t1 (id int constraint chk_id check(id=1) ) --表t2 create table t2 (id int ) --测试数据 insert into t2 values(1) insert into t2 values(2) insert into t2 values(3) insert into t2 values(4) insert into t2 values(5) --情况1 insert into t1 select id from t2 --结果:表中没有插入记录 --说明:虽然t2表中包含1,但是sql server将insert语句作为一个逻辑单元,由于原子性,所以未插入记录 --情况2 transaction begin tran insert into t1 select id from t2 insert into t1 values(1) commit --结果:t1中插入一条记录 --说明:单独的begin tran,commit不具有原子性 --情况3 set XACT_ABORT on begin tran insert into t1 select id from t2 insert into t1 values(1) commit --结果:表中没有插入记录 --说明:set XACT_ABORT 在语句失败时自动回滚(之前的如果正确还是执行,见情况4) --情况4 try catch begin try begin tran insert into t1 values(1) insert into t1 select id from t2 insert into t1 values(1) commit end try begin catch rollback print 'error' return end catch --结果:表中没有插入记录 --说明: try catch 使语句具有原子性
作者: koumingjie 发布时间: 2011-12-08
针对这个问题,我的解决办法是单独建立一个最大值管理表,每次需要用最大值时,先将最大值+1,再取出来
作者: koumingjie 发布时间: 2011-12-08
#2.在不同的隔离级别上,加的锁是不一样的
#3.事务只是为了保证完整性.在一个事务中,select行锁查询完就会释放,而排他锁会保持到事务结束
所以
问题1: 如果是多线程,即使在查询(select)最大值和插入这个最大值(insert)加入事务,也保证不了插入最大值的正确性.
问题2: 事务未结束前,另一个进程访问相同的数据,如果访问时没有锁冲突,就可以访问,否则等待.是否产生锁冲突决定于锁的类型,请注意上面讲的#3,就可以解答你的问题.
问题3: 参考问题1.你现在的解决的办法是对的.因为最大值管理表中的维护最大值是一行记录,你在更新这行记录时,会使这行记录拥有一个更新锁(最终会成为排他锁),保证了多进程访问时的正确性.
关于事务和锁的更多资料,请自己再学习一下,搞清楚它们之间的关系.
作者: wwwwgou 发布时间: 2011-12-08
#1.隔离级别
#2.锁
#3.事务
需要一一了解,才能贯通.
作者: wwwwgou 发布时间: 2011-12-08
SQL code
----原子性测试---
--表t1,id只能等于1
create table t1
(id int constraint chk_id check(id=1)
)
--表t2
create table t2
(id int
)
--测试数据
insert into t2 values(1)
insert into t2 values(2……
对于第一种情况,请使用@@error判断sql的执行结果。
作者: lang8134 发布时间: 2011-12-08
比如事务中使用SELECT ... FROM ... WITH (XLOCK,HOLDLOCK) ...
这样的语句,就会锁定一定的记录不允许其他进程读写,INSERT,UPDATE一般会自动加锁。
两个问题好像是一个问题,就上面的回答了
作者: Haiwer 发布时间: 2011-12-08
一个事务中只有多条select语句,由于默认的隔离级别下,select查询只会获得行共享锁,所以加事务是多余的;这时的一致性取决于SQL SERVER的隔离级别.
#1.隔离级别
#2.锁
#3.事务
需要一一了解,才能贯通.
我是在程序里加的事务
SqlTransaction transaction = connection.BeginTransaction();
这样加如果是多条select语句是不是也是行共享锁
作者: chopper7278 发布时间: 2011-12-08
作者: Haiwer 发布时间: 2011-12-08
引用 4 楼 wwwwgou 的回复:
一个事务中只有多条select语句,由于默认的隔离级别下,select查询只会获得行共享锁,所以加事务是多余的;这时的一致性取决于SQL SERVER的隔离级别.
#1.隔离级别
#2.锁
#3.事务
需要一一了解,才能贯通.
我是在程序里加的事务
SqlTransaction transaction = connection.Begi……
是的
作者: fredrickhu 发布时间: 2011-12-08
作者: fredrickhu 发布时间: 2011-12-08
是的
那怎么弄呢 一般大家是怎么做的呢 就是取最大值然后插入 或者是多条查询的时候

作者: chopper7278 发布时间: 2011-12-08
我是在程序里加的事务
SqlTransaction transaction = connection.BeginTransaction();
这样加如果是多条select语句是不是也是行共享锁
默认隔离级别下,是的.
作者: wwwwgou 发布时间: 2011-12-08
概念先理解,再代码,否则就算代码对了也没解决实际问题,稍有修改就会不知所措
作者: q465897859 发布时间: 2011-12-08
+1引用 8 楼 haiwer 的回复:
概念先理解,再代码,否则就算代码对了也没解决实际问题,稍有修改就会不知所措
我哭了///
作者: xiaolinyouni 发布时间: 2011-12-08
如果select默认是共享锁,那两个工作站同时select库存表,都认为库存足够,而执行下面的update语句,岂不是会造成数据错误。
怎样给select语句加排他锁
是这样吗:SELECT ... FROM ... WITH (XLOCK,HOLDLOCK)
作者: oracle185 发布时间: 2011-12-08
begin try
begin tran
insert into t1 values(1)
insert into t1 select id from t2
insert into t1 values(1)
commit
end try
begin catch
rollback
print 'error'
return
end catch
作者: tyxddgs 发布时间: 2011-12-08
一个事务中只有多条select语句,由于默认的隔离级别下,select查询只会获得行共享锁,所以加事务是多余的;这时的一致性取决于SQL SERVER的隔离级别.
#1.隔离级别
#2.锁
#3.事务
需要一一了解,才能贯通.
老师,在存储过程中怎样使用隔离级别和锁
作者: oracle185 发布时间: 2011-12-08
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28