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 在徐老 ...
随机推荐
- Codeforces1023E Down or Right 【贪心】
题目分析: 从起点开始询问终点连通性,优先右走.从终点开始询问起点连通性,优先上走. 代码: #include<bits/stdc++.h> using namespace std; in ...
- LOJ6436 [PKUSC2018] 神仙的游戏 【FFT】
题目分析: 题目要求前后缀相同,把串反过来之后是一个很明显的卷积的形式.这样我们可以完成初步判断(即可以知道哪些必然不行). 然后考虑一下虽然卷积结果成立,但是存在问号冲突的情况. 箭头之间应当不存在 ...
- BZOJ4818 [SDOI2017] 序列计数 【矩阵快速幂】
题目分析: 一个很显然的同类项合并.注意到p的大小最大为100,考虑把模p意义下相同的求出来最后所有的减去没有质数的做矩阵快速幂即可. 代码: #include<bits/stdc++.h> ...
- Matplotlib学习---用matplotlib画面积图(area chart)
这里利用Nathan Yau所著的<鲜活的数据:数据可视化指南>一书中的数据,学习画图. 数据地址:http://book.flowingdata.com/ch05/data/us-pop ...
- kebab HDU - 2883(按时间段建点)
题意: 有n个人去撸串,每个人都能决定自己的串上有几块肉,每一块肉都要花费一个单位时间才熟,烤炉一次能烤m块肉 给出每个人的起始时间.终止时间.要几串.每个串上有几块肉,问能否满足所有的人 (啥?题不 ...
- Android 播放Gif 动画
在Android 中是不支持直接使用Gif 图片关联播放帧动画,如下动画在Android 中是无法播放的: Android 提供了另外一种解决的办法,就是使用AnimationDrawable 这一函 ...
- 【mysql】 mysql忘记密码
先关闭mysql服务 [root@localhost ~]# service mysql status Redirecting to /bin/systemctl status mysql.servi ...
- __init__和__new__的异同
实例化类的流程: 1.p = Person(name, age)2.首先执行使用name和age参数来执行Person类的__new__方法,这个__new__方法会 返回Person类的一个实例(p ...
- java 子类强转父类 父类强转子类
Java 继承 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为. Java 子类强转父类 父类引用指向子类对象: jav ...
- Qt5应用改变窗口大小时出现黑影
解决方法 在启动程序时,添加-platform wayland参数 添加QT_QPA_PLATFORM=wayland-egl到系统环境变量 注意:改完后虽然没有黑影,但软件图标显示不正常,也不能正常 ...