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 在徐老 ...
随机推荐
- Voltage Keepsake CodeForces - 801C (贪心 || 二分)
C. Voltage Keepsake time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- mysql 2006错误 导入时
导入数据库报此错误 1.找到my.ini (免安装版的是由于你自己创建的) (安装版的在 C:\ProgramData\MySQL\MySQL Server 8.0 你安装的盘位置) 2.修改参数 ...
- U盘启动盘还原
cmd运行 diskpart list disk clean 一般都是disk 1,不过最好先list查一下 右击桌面上的计算机图标,选择管理,进入磁盘管理,能看到u盘分区是未分配的(黑色),右击,新 ...
- 分数规划模板(洛谷P4377 [USACO18OPEN]Talent Show)(分数规划,二分答案,背包)
分数规划是这样一个东西: 给定若干元素,每个元素有两个属性值\(a_i,b_i\),在满足题目要求的某些限制下选择若干元素并求出\(\frac{\sum a}{\sum b}\)的最大值. 如果没有限 ...
- zabbix3.4.6之自动发现与自动注册
在zabbix中添加新主机时,是需要手动添加,但在zabbix的Action里有两项功能,自动发现与自动注册,运用这两个功能中任意一个都可以实现自动添加机器,但添加的主机名是IP地址. 自动发现:添加 ...
- docker_flannel
目录 一.安装etcd 安装 运行 验证 二.安装和配置 flannel 三. Docker 中使用 flannel 配置 Docker 连接 flannel 容器连接到 flannel 网络 四.f ...
- 常用CSS样式速查
writing-mode: vertical-lr; -webkit-writing-mode: vertical-lr; -ms-writing-mode: vertical-lr; 作用 CSS ...
- [国家集训队]middle 解题报告
[国家集训队]middle 主席树的想法感觉挺妙的,但是这题数据范围这么小,直接分块草过去不就好了吗 二分是要二分的,把\(<x\)置\(-1\),\(\ge x\)的置\(1\),于是我们需要 ...
- 解决使用jedis连接是报DENIED Redis is running in protected mode错误
DENIED Redis is running in protected mode because protected mode is enabled, no bind address was spe ...
- UVALive - 4222
题目链接:https://vjudge.net/contest/244167#problem/D 题目: For a dance to be proper in the Altered Culture ...