AOD.NET实现数据库事物Transaction
在开始介绍文章主要内容前先简单说一下事务
1.事务介绍
事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。
2.事务使用场景
需要对数据库同时进行多条更新操作时!例如,电商平台的下单付款,银行转账之类的
好了,这里就不对事物进行细说了,想了解更多与事务有关的详细知识可以去园子里搜索哈
执行事务的步骤
1.连接数据库,连接数据库后会返回一个SqlConnection对象,我这里在数据库连接后将其赋值给了一个全局的SqlConnection对象——_con
2.用返回的SqlConnection对象用BeginTransaction()方法生产并开始一个事务对象。
3.执行所有对数据库进行更改操作的Sql语句。
在对数据库进行更改时需要用到SqlCommand,在用生成SqlCommand对象后必须给其绑定事务(Transaction),不绑定会报错。
在这里需要注意的是所有SqlCommand对象绑定的SqlConnection必须是同一个SqlConection对象,所有SqlCommand对象绑定的事务对象必须是同一个事务对象。若没绑定相同的SqlConnection对象和SqlTransaction,事务便会如同虚设。
4.所有Sql语句执行成功后SqlTransaction对象可使用Commit()方法提交事务,失败则用Rollback()回滚事务,将数据库回滚到第一天sql执行前的状态。
5.关闭数据库连接,释放资源。
话不多说搬Code,注释代码上都有,如有不明白的地方或是有更好的意见请在下方留言区留下你的评论
事务方法
public static int ModifyDatabaseTran(List<string> SqlStrList, List<SqlParameter[]> SqlParList) {
int result = ;
//打开数据库连接
SqlConnection con = OpenDatabase();
//_con:全局SqlConnection对象
//生成事物对象
SqlTransaction tran = _con.BeginTransaction();
try
{
//遍历并执行SqlStrList集合里面的Sql语句
for (int i = ; i < SqlStrList.Count; i++)
{
//将Sql语句与其对应的SqlParameter[]绑定并生成SqlCommand对象
SqlCommand com = BulidCommand(SqlStrList[i], SqlParList[i]);
//给SqlCommand对象绑定事务,必须绑定同一个事务对象否则跑不出事务效果
com.Transaction = tran;
//返回受影响的行数
result = com.ExecuteNonQuery();
}
//若最后执行的sql是插入语句result的值便=0,这里将其值改为1告诉调用者sql语句执行成功
if (result == ) result = ;
//所有Sql语句执行成功后提交事务
tran.Commit();
}
catch (Exception)
{
//SqlStrList集合里面有一条Sql语句执行失败便执行事务回滚操作,回滚后报错Sql语句之前执行的Sql语句都将无效
//同时数据库恢复SqlStrList集合里面的Sql语句执行前的状态
result=0;
tran.Rollback();
}
finally
{
//关闭数据库连接,释放资源
if (_con != null && _con.State != ConnectionState.Closed) {
_con.Close();
con.Dispose();
}
tran.Dispose();
}
//返回结果 0:失败,1:成功
return result;
}
打开数据库连接的方法
//数据库连接字符串
private const string conStr = "server=.;database=Food;uid=sa;pwd=123456"; private static SqlConnection _con; /// <summary>
/// 打开数据库连接
/// </summary>
/// <returns></returns>
private static SqlConnection OpenDatabase() {
if (_con == null || _con.State == ConnectionState.Closed)
{
_con = new SqlConnection(conStr);
_con.Open();
}
return _con;
}
生产SqlCommand对象方法
/// <summary>
/// 参数化查询绑定参数
/// </summary>
/// <param name="sqlStr"></param>
/// <param name="SqlPar"></param>
/// <returns></returns>
private static SqlCommand BulidCommand(string sqlStr,SqlParameter[] SqlPar) {
SqlConnection con = OpenDatabase();
SqlCommand com = new SqlCommand(sqlStr, con);
com.Parameters.AddRange(SqlPar);
return com;
}
实例
下面例子本来是想用winform写个注册,结界觉着拖控件太麻烦了,索性就直接在代码里面写sql了
页面(输入框可以自动忽略,这里只用到了按钮的点击事件)

执行操作前的member表状态

注册按钮点击事件代码(页面控件是从登陆页面复制过来的注册按钮的Name属性没有更改所以事件名称是LoginBtn_Click而不是RegisterBtn_Click)
private void LoginBtn_Click(object sender, EventArgs e)
{
List<string> sqlStr = new List<string>
{
{ @"insert member values(@MemberAccount,@Password)"},
{ @"insert member values(@MemberAccount,@Password)"}
};
List<SqlParameter[]> sqlPar = new List<SqlParameter[]>
{
new SqlParameter[] { new SqlParameter("@MemberAccount","lei1"), new SqlParameter("@Password", "") },
new SqlParameter[] { new SqlParameter("@MemberAccount","lei2"), new SqlParameter("@Password", "") }
}; int result=DBHlep.ModifyDatabaseTran(sqlStr,sqlPar);
if (result > )
{
MessageBox.Show("成功!");
}
else {
MessageBox.Show("失败!");
}
}
点击注册按钮后我们再来看看member表状态

上面的是Sql语句不报错的执行结果,接下来,我们将第二条sql语句的表名从menber改为menber1,看看member表的数据会发生什么变化
PS:我的数据库里面没有表member1所以第二条sql必定会执行失败,第二条sql失败后我们看看表member是否新增了一条数据(第一条sql是正确的,只修改了第二条sql的表名),新增了一条数据则事务执行失败,反之事务执行成功
private void LoginBtn_Click(object sender, EventArgs e)
{
List<string> sqlStr = new List<string>
{
{ @"insert member values(@MemberAccount,@Password)"},
//将第二条sql的表名修改为member1
{ @"insert member1 values(@MemberAccount,@Password)"}
};
List<SqlParameter[]> sqlPar = new List<SqlParameter[]>
{
new SqlParameter[] { new SqlParameter("@MemberAccount","lei1"), new SqlParameter("@Password", "") },
new SqlParameter[] { new SqlParameter("@MemberAccount","lei2"), new SqlParameter("@Password", "") }
}; int result=DBHlep.ModifyDatabaseTran(sqlStr,sqlPar);
if (result > )
{
MessageBox.Show("成功!");
}
else {
MessageBox.Show("失败!");
}
}
点击注册按钮后看表member的数据是否发生了变化

member表数据未发生变化,事务执行成功!
好了,这篇博客到这里就结束了,如有不明白之处或是有更好的意见请在下方留言区留下你的评论
AOD.NET实现数据库事物Transaction的更多相关文章
- 数据库事物四大特性-ACID
事务的:原子性.一致性.分离性.持久性 事物(transaction)是由一些列操作序列构成的执行单元,这些单元要么都做,要么不做,是一个不可分割的工作单元. 数据库事物的四个基本性质(ACID) 1 ...
- SpringBoot事物Transaction实战讲解教程
前言 本篇文章主要介绍的是SpringBoot的事物Transaction使用的教程. SpringBoot Transaction 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码 ...
- 数据库事物用法 SET XACT_ABORT ON
数据库事物的用法和作用就不再重复,写一下在实战当中遇到的问题,代码如下: begin tran --开始执行事务 --语句一 update set acount = acount-100 w ...
- Spring中的数据库事物管理
Spring中的数据库事物管理 只要给方法加一个@Transactional注解就可以了 例如:
- 数据库事物 jdbc事物 spring事物 隔离级别:脏幻不可重复读
1.数据库事物: 事物的概念 a给b打100块钱的例子 2.jdbc事物: 通过下面代码实现 private Connection conn = null; private PreparedState ...
- Spring+Mybatis+SpringMVC+Atomikos多数据源共存+不同数据库事物一致性处理
网上找了一大堆的例子,没一个跑通的,都是copy转发,哎,整理得好辛苦..做个笔记,方便正遇到此问题的猿们能够得到帮助....废话不多说,贴代码..... 项目结构说明: 1.dao层的admin.w ...
- Spring 事物Transaction
日常开发中Spring 为我们提供了两种事物的定义方式 XML 配置 方式 :这种方式配置起来比较麻烦,但后期比较好进行维护 注解方式:配置起来比较方便,也是日常开发常用的: 我们这里进行第二种注解的 ...
- 数据库事务(Transaction)
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 事务四大特性(ACID): 原子性(Atomicity):个事务是一个不可分割的工作单位,事务中包括的 ...
- SQL Server 2008 中收缩数据库(DUMP,TRANSACTION,TRAN,无效,语法错误)
从SQL SERVER 2008 开始,我们已经不能再用以前 DUMP TRAN 数据库名 WITH NO_LOG 的这种方式来收缩数据库,但是,可以用另外一种替代的方法,SQL语句如下: ALTER ...
随机推荐
- python从入门到放弃--线程进阶
# ### 死锁,递归锁,互斥锁 from threading import Thread,Lock import time noodle_lock = Lock() kuaizi_lock = Lo ...
- MYSQL第一课
rm-rf /* 不能用 完全删除 数据库不能直接存储数据 table 表 DB 数据库 DBMS 数据库操作系统 SQL 结构化查询语言 语句不区分大小写,但字符串常量区区分大小写.建议命令大写. ...
- linux 添加用户并设置主目录,shell 并赋予权限 (以 fedora 和 ubuntu 为例)
环境 centos 7.6 添加用户: [root@localhost ~]# useradd -d /home/yaoxu -m -s /bin/bash yaoxu 更改用户密码: passwd ...
- JavaScript—数据可视化(ECharts)
Echarts具有丰富的图表,可以说是数据可视化的神器: 1.下载Echarts 官网下载地址:https://echarts.baidu.com/index.html 2.Echarts引用案例—柱 ...
- BASIC合集
握手包 给你握手包,flag是Flag_is_here这个AP的密码,自己看着办吧. 提交格式:flag{WIFI密码} 破解wifi密码 丢到kali,用aircrack-ng kali有一个包含常 ...
- Java连载37-面向对象的封装性
一.IDE上继续新建工程 1.在src目录下新建软件包:package机制后面再讲,目前先用着 2.给package命名一个名称:com.bjpowernode.java_learning 3.软件包 ...
- ndt算法学习
NDT算法原理: NDT算法的基本思想是先根据参考数据(reference scan)来构建多维变量的正态分布, 如果变换参数能使得两幅激光数据匹配的很好,那么变换点在参考系中的概率密度将会很大. 因 ...
- 获取主机信息,网络信息AIP,getsockname,getpeername,getservbyname,getservbyport,inet_ntop,inet_pton
获取主机信息 1.ip地址转换,主机字节序 <---> 网络字节序 #include <arpa/inet.h> int inet_pton(int af, const cha ...
- Sencha Modern
Sencha Modern 前言 经过一个月捣鼓,基于sencha公司最新框架版本 ExtJS7.0 modern 的示例代码可以和大家见面了.示例中对系统主题.公共(组件,方法)封 ...
- vsftpd限制下载流量
有时候我们在公司为了考虑业务,流量以及用户数问题会做一些限制操作,今天我们来看一下vsftpd是怎么做限流的 在vsftpd配置文件中添加如下内容 为了方便测试我们临时生成一个文件 接下来我们开始测试 ...