代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性
做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线、真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程(存储过程加事务),完成了一个功能的实现就万事大吉了,这次想换一种新的方法:经过和师哥的交流学习,在代码中使用事务同样也是可以解决问题的,可以保证数据的正确性,就像银行取款一样,如果在取款的过程中取款机出现故障,我们个人的账户上的金额不会受任何影响等。
代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作。
首先是在D层添加一个类为了保存当前操作的这一个连接放到一个事务中执行,并事务执行打开同一个连接、事务完成关闭同一个连接的一个共有类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Maticsoft.DBUtility;
namespace PersonalFiles.DAL
{
public class DBTransaction
{
private DbHelperSQL SqlHelper = null; public DBTransaction()
{
SqlHelper = new DbHelperSQL();
} /// <summary>
/// 获取数据库连接
/// </summary>
/// <returns></returns>
public SqlConnection GetConnection()
{
return SqlHelper.GetCon();
} /// <summary>
/// 获取事务
/// </summary>
/// <returns></returns>
public SqlTransaction GetTransaction(SqlConnection conn)
{
return conn.BeginTransaction();
} /// <summary>
/// 提交事务
/// </summary>
public void Commit(SqlTransaction sqlTransaction)
{
sqlTransaction.Commit();
} /// <summary>
/// 回滚事务
/// </summary>
public void Rollback(SqlTransaction sqlTransaction)
{
sqlTransaction.Rollback();
} /// <summary>
/// 关闭连接
/// </summary>
public void Close(SqlConnection conn)
{ if (conn.State == ConnectionState.Open)
{
conn.Close();
} }
}
}
界面层的后台代码和以前一样直接调去就行了,现在来看主要是在B层中的代码发生了很大的变化,需要向下层传递事务与获取的连接
/// <summary>
/// 增加一条数据
/// </summary>
public void Add(PersonalFiles.Model.BasicInformation modelBasic, PersonalFiles.Model.T_HumanAgency model)
{
int flag = 0; DBTransaction DbTran = new DBTransaction(); //获得连接
SqlConnection conn = DbTran.GetConnection(); //开启事务
SqlTransaction trans = DbTran.GetTransaction(conn);
try
{
//把获得的同一个连接与事务一共传下去
//dalBasic.Add(modelBasic,conn,trans); //把获得的同一个连接与事务一共传下去 dalAgency.Add(model,conn,trans); //事务提交
DbTran.Commit(trans);
//return true;
} catch (Exception ex)
{
//回滚事务
DbTran.Rollback(trans);
}
finally
{
DbTran.Close(conn);
}
}
注意的是向D层传是我们需要传的是B层获取的同一个连接于开启的是一个事务:
/// <summary>
/// 增加一条数据
/// </summary>
public void Add(PersonalFiles.Model.T_HumanAgency model,SqlConnection conn,SqlTransaction trans)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("insert into T_HumanAgency(");
strSql.Append("myidentity,relation,receivemode,workingtime,intotime,oldworkplace,nowworkplace,inervice,registered,registeredcardid,registeredid,householder,isrecord,fileintotime,fileouttime,filetowhere,relationouttime,Paymentstandard,paymentsmonth,payments,stoptime,state,pri,admin,ID)");
strSql.Append(" values (");
strSql.Append("@myidentity,@relation,@receivemode,@workingtime,@intotime,@oldworkplace,@nowworkplace,@inervice,@registered,@registeredcardid,@registeredid,@householder,@isrecord,@fileintotime,@fileouttime,@filetowhere,@relationouttime,@Paymentstandard,@paymentsmonth,@payments,@stoptime,@state,@pri,@admin,@ID)");
SqlParameter[] parameters = {
new SqlParameter("@myidentity", SqlDbType.VarChar,50),
new SqlParameter("@relation", SqlDbType.VarChar,50),
new SqlParameter("@receivemode", SqlDbType.VarChar,50),
new SqlParameter("@workingtime", SqlDbType.VarChar,50),
new SqlParameter("@intotime", SqlDbType.VarChar,50),
new SqlParameter("@oldworkplace", SqlDbType.VarChar,50),
new SqlParameter("@nowworkplace", SqlDbType.VarChar,50),
new SqlParameter("@inervice", SqlDbType.VarChar,50),
new SqlParameter("@registered", SqlDbType.VarChar,50),
new SqlParameter("@registeredcardid", SqlDbType.VarChar,50),
new SqlParameter("@registeredid", SqlDbType.VarChar,50),
new SqlParameter("@householder", SqlDbType.VarChar,50),
new SqlParameter("@isrecord", SqlDbType.VarChar,50),
new SqlParameter("@fileintotime", SqlDbType.VarChar,50),
new SqlParameter("@fileouttime", SqlDbType.VarChar,50),
new SqlParameter("@filetowhere", SqlDbType.VarChar,50),
new SqlParameter("@relationouttime", SqlDbType.VarChar,50),
new SqlParameter("@Paymentstandard", SqlDbType.VarChar,50),
new SqlParameter("@paymentsmonth", SqlDbType.VarChar,50),
new SqlParameter("@payments", SqlDbType.VarChar,50),
new SqlParameter("@stoptime", SqlDbType.VarChar,50),
new SqlParameter("@state", SqlDbType.VarChar,50),
new SqlParameter("@admin", SqlDbType.VarChar,50),
new SqlParameter("@pri", SqlDbType.VarChar,50),
new SqlParameter("@ID", SqlDbType.VarChar,50)};
parameters[0].Value = model.myidentity;
parameters[1].Value = model.relation;
parameters[2].Value = model.receivemode;
parameters[3].Value = model.workingtime;
parameters[4].Value = model.intotime;
parameters[5].Value = model.oldworkplace;
parameters[6].Value = model.nowworkplace;
parameters[7].Value = model.inervice;
parameters[8].Value = model.registered;
parameters[9].Value = model.registeredcardid;
parameters[10].Value = model.registeredid;
parameters[11].Value = model.householder;
parameters[12].Value = model.isrecord;
parameters[13].Value = model.fileintotime;
parameters[14].Value = model.fileouttime;
parameters[15].Value = model.filetowhere;
parameters[16].Value = model.relationouttime;
parameters[17].Value = model.Paymentstandard;
parameters[18].Value = model.paymentsmonth;
parameters[19].Value = model.payments;
parameters[20].Value = model.stoptime;
parameters[21].Value = model.state;
parameters[22].Value = model.pri;
parameters[23].Value = model.admin;
parameters[24].Value = model.ID; //DbHelperSQL.ExecuteSql(strSql.ToString(), parameters);
DbHelperSQL.ExecuteSql(strSql.ToString(),conn,trans, parameters);
}
在代码中添加事务与存储过程中添加事务的异同
相同点
1:都能够保证数据的一致性。
不同点:
1:代码中添加事务的好处是:增加了代码的可读性、与可维护性,方便后期人员维护系统看代码能够一目了然的看懂代码,而在数据库中添加存储过程的可读性不是很好。
2:为什么不建议使用数据库自带的存储过程+事务呢?主要是一个项目过多的依赖数据库,这样对后期的数据库迁移都会带来一定的影响与不便(sql向oracle迁移),好多转换不是很容易兼容性和不是很好(以后再深入学习)。
3:合作开发时如果是代码中添加事务遵循了代码上传的原则,这样方便大家的交流。
为什么使用事务可以保证同一个连接向数据库多个表写信息的正确性与一致性的原理:
事务的原子性
事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据改操作要全部执行,要么全部不执行。这种特性称为原子性。 事务的原子性要求,如果把一个事务看作是一个程序,它要么完整的被执行,要么完全执行。就是说事务的操纵序列或者完全应用到数据库或者完全不影响数据库。这种特性称为原则性 假如用户在一个事务内完成了对数据库的更新,这时所有的更新对外部世界必须是可见的,或者完全没有更新。前者称事务已提交,后者称事务撤销。DBMS必须确保由成功提交的事物完成的所有操作在数据库内有完全的反映,而失败的事务对数据库完全没有影响
事务的隔离性
事务开始执行了但是没有提交事务,数据并没有真正的写到数据库里面,当我去断点测试的时候当第一个程序向数据库发出写完时,我去查找数据库不能打开数据库,不能查找,提示连接超时,由于事务的隔离性,数据并没有真正的写到数据库里面,等事务提交才可以查到数据库,可见同一个连接下执行的程序在同一个事务执行的开始于结束后才真正写到数据库里面,如果过程当中保存事务回滚,数据不会写到数据库里面。保证数据的一致性与正确性。
数据的准确性与一致性是我们要时刻考虑的,一个好的系统必须有较好的准确性才能保证用户的使用。
代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性的更多相关文章
- 在易语言中调用MS SQL SERVER数据库存储过程方法总结
Microsoft SQL SERVER 数据库存储过程,根据其输入输出数据,笼统的可以分为以下几种情况或其组合:无输入,有一个或多个输入参数,无输出,直接返回(return)一个值,通过output ...
- Ado.Net实体数据模型EF,如何在代码中添加数据库连接密码
在创建EF模型的时候,VS2013提示说“在连接字符串中存储敏感数据可能有安全风险”,于是我选择了在代码中添加,可是如何通过代码添加呢? 我在网上百度了下,没有人说的清楚直观. 假设我们创建了一个名字 ...
- 移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签)
移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签) 一.总结 一句话总结: 添加viewport标签:meta name="viewport" ...
- MySQL--视图view、触发器trigger、事务(start transaction)、存储过程(特殊的数据逻辑处理函数)、流程控制(if,case....)
mysql致力于项目开发及数据库管理之间解耦合(帮忙封装一些数据处理方法,使应用程序的开发者可以专注于应用程序的开发),但受限于不同部门沟通的成本问题,现阶段直接使用的价值不大. 一.视图(只能sel ...
- springmvc 事务控制与数据库隔离级别
springmvc 事物传播与数据库隔离控制 http://www.cnblogs.com/yangy608/archive/2011/06/29/2093478.html 一.Propagation ...
- unity中添加音量控制的一些步骤
1.先确认要控制的音源(Audio Source)所使用的输出(Output),例如我这里BGM使用的是MainMixer: 2.暴露音量(Volume)参数,让脚本可以控制.这里如果不暴露出来,脚本 ...
- (转)Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。
在使用 Unity3d 倒入Fbx模型的时候,动画的动画片段需要自己手动添加模型多了以后会是一个不小的工作量. Unity3d支持 编辑器脚本来控制资源导入的过程.添加一个 AssetPostproc ...
- 如何优雅的在 vue 中添加权限控制
前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...
- 如何在 vue 中添加权限控制管理?---vue中文社区
前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...
随机推荐
- php快递查询
http://www.oschina.net/code/snippet_60100_25087 <?php class Express { private $expressname =array ...
- relatedTarget, fromElement, toElement
原文:http://www.quirksmode.org/js/events_mouse.html#relatedtarget W3C在mouseover和mouseout事件中添加了relatedT ...
- JavaEE Tutorials (23) - 资源适配器和契约
23.1什么是资源适配器362 23.1.1管理契约363 23.1.2通用工作上下文契约364 23.1.3出站和入站契约36423.2元数据注解36523.3公共客户端接口36623.4对Java ...
- JAVA的IO运用
IO OF JAVA想写好一篇关于JAVA的IO的文章不容易,因为它涉及的东西很多难以写得有深度和有思路.我虽不才但也写.这篇文章有我个人不少的见解,虽然涉足计算机不深但我不想用一大堆这个可能那个可能 ...
- 【原】win7下调整分区
由于装系统时硬盘分区极度不合理,导致现在装一些比较大的开发软件根本不能装,但是又不想重装系统调整分区,而且还不想让已有的文件受到一点伤害,毕竟数据无价啊.几番搜索后,发现了一款比较好用的硬盘管理软件 ...
- 关于我们-成功人士西装定制服务第一品牌派斯特PAISTETAILOR绅士礼服
关于我们-成功人士西装定制服务第一品牌派斯特PAISTETAILOR绅士礼服 北京派思特服装服饰有限公司国内领先绅士男装定制品牌PAISTETAILOR,引领男装定制的领航者.
- error: C2664: “zajiao::zajiao(const zajiao &)”: 无法将参数 1 从“const char [12]”转换为“char *”
原本打算在QT用一个字符串"ABCDEF12345"作为类zajiao的构造函数的参数,用来创建类zajiao的对象zajiao1. zajiao zajiao1("AB ...
- AlertView点击确定后再执行后面的代码
AlertView的show方法执行后,后面的代码会继续运行,而不会等待用户按键结束再走,这样,如果把弹出的代码写在一个BOOL函数里,没等用户确认直接返回NO就惨了,解决方法: - (BOOL)be ...
- 关于写的Java书籍进展
大家好,去年说要写本Java书,近期就快出版了.眼下已经開始打印样书了,最快于本月中旬左右就能够在互动网www.china-pub.com上看到消息,其它各个站点何时会发售要看详细进货情况. 去年我预 ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3 正式宣布
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件.广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...