SqlServer中的事务使用
一、事务的概念和特点
事务(transaction)是恢复和并发控制的基本单位。
事务的特点
原子性:事务是一个工作单元,要都成功,要么的失败
例子:A付款给B,A余额-100,B余额+100,只能都成功或者都失败,不能把A的钱扣了,而B的没加上
一致性:必须让数据库从一个一致状态到另一个一致状态
例子:还是上边的例子,A和B的总余额没有改变(保持了一致性)
隔离性:事务之间互不影响,并发执行的事务之间互不干扰(通过锁来实现的)
例子:A给B付款 和 C给B付款是两个事务,A付A的,C付C的,互不干扰。
持久性:事务对数据的改变时永久性的。
例子:A付款后,A的余额确实少了100,B的余额多了100(数据库中的记录确实改变了)
二、事务的使用
还是用付款的例子,先添加以下测试数据
--创建一个账户表,添加约束,余额(money)不小于零
create table Tb_bankAcount(
Id int identity(1,1) primary key,
Name nvarchar(20) not null,
Money int not null
)
alter table Tb_bankAcount
add constraint CK_money CHECK(money>=0)
--添加数据
insert into Tb_bankAcount values('A',200)
insert into Tb_bankAcount values('B',200)
2.1 sql中使用事务
begin transaction --开启事务
declare @errorCount int=0;--记录错误的变量
update Tb_bankAcount set Money-=500 where Name='A'
set @errorCount+=@@ERROR
update Tb_bankAcount set Money+=500 where Name='B'
set @errorCount+=@@ERROR if @errorCount>0 --有错误就回滚
rollback transaction
else --没有错误提交
commit transaction
上边的代码执行时A用户的余额为200-500=-300,由于不满足约束条件(Money>0),执行回滚
2.2 Ado.Net中使用事务(SqlTransaction形式)
using (SqlConnection conn = new SqlConnection(connStr))
{
//要执行的sql脚本
string sqlText = @"update Tb_bankAcount set Money-=100 where Name='A'
update Tb_bankAcount set Money+=100 where Name='B'";
conn.Open();
//创建事务
SqlTransaction tran = conn.BeginTransaction();
using (SqlCommand com = new SqlCommand(sqlText, conn))
{
try
{
//开启事务
com.Transaction = tran;
com.ExecuteNonQuery();
//提交事务
tran.Commit();
Console.WriteLine("事务执行成功");
}
catch (Exception ex)
{
//回滚事务
tran.Rollback();
Console.WriteLine(ex.Message);
}
}
}
上边的代码执行时,由于满足约束条件(Money>0),执行事务提交。
使用SqlTransaction执行事务时,每个事务都是基于SqlConnection的,如果我们的事务要跨越多个程序集或者使用多个数据库时,使用SqlTransaction来实现事务就比较麻烦了,针对这个问题.net 2.0出现了TransactionScope
2.3 Ado.Net中使用分布式事务(TransactionScope形式)
static void Main(string[] args)
{
//连接字符串
string connstr1 = @"your connctionString1";
string connstr2 = @"your connctionString2"; using (TransactionScope ts = new TransactionScope())
{
#region 执行任务1
using (SqlConnection conn1 = new SqlConnection(connstr1))
{
using (SqlCommand com = conn1.CreateCommand())
{
conn1.Open();
com.CommandText = "delete from t_stu where id=10";
com.ExecuteNonQuery();
}
}
#endregion #region 执行任务2
using (SqlConnection conn2 = new SqlConnection(connstr2))
{
using (SqlCommand com = conn2.CreateCommand())
{
conn2.Open();
com.CommandText = "insert into t_stu(stuname,age) values ('zs',22')";
com.ExecuteNonQuery();
}
}
#endregion
//通过ts.Complete()方法进行提交
ts.Complete();
}
}
上边的代码十分简单,我们可以看到使用TransactionScope可以轻松的构建分布式的事务模型,conn1和conn2两个连接可以连接不同的数据库。TransactionScope实现了IDispose()接口,我们可以使用using语法糖来自动释放资源。执行TransactionScope时会依此执行TranactionScope的所有代码,当执行到ts.Complete()时表示事务中的任务都执行完成了,进行提交。如果不显示地执行ts.Complete()方法,TransactionScope中代码执行完毕后执行回滚操作。
事务在数据库和业务编码中十分重要,这里只是简单地介绍了.net平台下事务的基本用法,如果有不合理的地方,欢迎指出。
SqlServer中的事务使用的更多相关文章
- 【SqlServer】解析SqlServer中的事务
目录结构: contents structure [+] 事务是什么 控制事务 数据并发访问产生的影响 事务的隔离级别 锁 NOLOCK.HOLDLOCK.UPDLOCK 死锁分析 在这篇Blog中, ...
- SQLServer中的事务与锁
事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁:是数据库性能的 ...
- SqlServer中的事务隔离级别、锁机制
事务 作用:用来执行一连串的动作,并且保证所有动作要么都执行.要么都不执行. 属性:原子行.一致性.隔离性.持久性 锁 作用:SqlServer使用锁来实施事务隔离属性. 阻塞 定义:如果一个事务持有 ...
- sqlserver中的锁与事务
以下内容整理自: SQL Server中的锁 SQLSERVER中的元数据锁 SQLSERVER中的锁资源类型 浅谈sqlserver中的事务和锁 锁的分类 1.从数据库角度 独占锁(排它锁 X) 独 ...
- Sqlserver 存储过程中结合事务的代码
Sqlserver 存储过程中结合事务的代码 --方式一 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ ...
- SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题
转自 :SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题 问题: 1. System.Data.SqlClient.SqlExcepti ...
- C#批量插入数据到Sqlserver中的四种方式
我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...
- Sqlserver中一直在用又经常被忽略的知识点一
已经有快2个月没有更新博客了,实在是因为最近发生了太多的事情,辞了工作,在湘雅医院待了一个多月,然后又新换了工作...... 在平时的工作中,Sqlserver中许多知识点是经常用到的,但是有时候我们 ...
- SQLSERVER中的假脱机spool
SQLSERVER中的假脱机spool 我发现网上对于假脱机的解释都非常零散,究竟假脱机是什么? 这几天在家里研究了一下,收集了很多网上的资料 假脱机是中文的翻译,而英文的名字叫做 spool 在徐老 ...
随机推荐
- flask之三方组件
Flask-session Flask-session跟框架自带的session有什么区别呢 框架自带的session是通过请求上下文~放入到Local中的~那如果我们想把session放入别的地方怎 ...
- Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)
A. Technogoblet of Fire 题意:n个人分别属于m个不同的学校 每个学校的最强者能够选中 黑客要使 k个他选中的可以稳被选 所以就为这k个人伪造学校 问最小需要伪造多少个 思路:记 ...
- HDU1506 Largest Rectangle in a Histogram(算竞进阶习题)
单调栈裸题 如果矩形高度从左到右是依次递增,那我们枚举每个矩形高度,宽度拉到最优,计算最大面积即可 当有某个矩形比前一个矩形要矮的时候,这块面积的高度就不能大于他本身,所以之前的所有高于他的矩形多出来 ...
- 【XSY2785】模型
题目描述 给你一棵\(n\)个点的树,让你加最少的边,使得图中没有割点. 要求输出方案. \(n\leq 500000\) 题解 把叶子的权值设为\(1\),其他点设为\(0\),找出带权重心. 以重 ...
- TP5调用微信JSSDK 教程 —— 之异步使用
细节请参考前一篇文章:JSSDK.PHP 修改下: <?php namespace jssdk; class Jssdk { private $appId; private $appSecret ...
- composer阿里云短信服务不支持传参为数值--为2017年短信接口,2018阿里云有更新http://www.cnblogs.com/q1104460935/p/8916096.html
composer 阿里云短信服务使用 xuying/aliyun_mns 更新到2017年初,不再更新 ){;, ); }; } ; }; }; }} 以下为发送成功返回对象 object(A ...
- 【BZOJ2576】[JSOI2011]序的计数 (动态规划)
[BZOJ2576][JSOI2011]序的计数 (动态规划) 题面 BZOJ 题解 首先构建一个新的虚拟节点连接所有目标节点,强行将其作为第一个被访问的节点,这样子就解决了图不连通的问题. 除了目标 ...
- sql语句循环截取字符串
测试环境 : mssql2016 express 需求 : 拆分字符串执行insert 思路 : 在循环中截取分隔符之间的字符串.起止点位置计算 起点从0开始startIndex,查找第一个分隔 ...
- 简单使用TFS管理源代码
今天研究使用了一下TFS,主要是想管理源代码.不涉汲团队管理. 使用环境W10专业版 / VS2017 社区版 / SQLSERVER2016 / TFS2017 EXPRESS版本 1.下载和安 ...
- 「TJOI2015」组合数学 解题报告
「TJOI2015」组合数学 这不是个贪心吗? 怎么都最小链覆盖=最大点独立集去了 注意到一个点出度最多只有2,可以贪心一下出度的去向 按读入顺序处理就可以,维护一个\(res_i\)数组,表示上一行 ...