做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线、真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程(存储过程加事务),完成了一个功能的实现就万事大吉了,这次想换一种新的方法:经过和师哥的交流学习,在代码中使用事务同样也是可以解决问题的,可以保证数据的正确性,就像银行取款一样,如果在取款的过程中取款机出现故障,我们个人的账户上的金额不会受任何影响等。

代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作。

首先是在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(数据库存储过程+事务) 保证数据的完整性与一致性的更多相关文章

  1. 在易语言中调用MS SQL SERVER数据库存储过程方法总结

    Microsoft SQL SERVER 数据库存储过程,根据其输入输出数据,笼统的可以分为以下几种情况或其组合:无输入,有一个或多个输入参数,无输出,直接返回(return)一个值,通过output ...

  2. Ado.Net实体数据模型EF,如何在代码中添加数据库连接密码

    在创建EF模型的时候,VS2013提示说“在连接字符串中存储敏感数据可能有安全风险”,于是我选择了在代码中添加,可是如何通过代码添加呢? 我在网上百度了下,没有人说的清楚直观. 假设我们创建了一个名字 ...

  3. 移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签)

    移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签) 一.总结 一句话总结: 添加viewport标签:meta name="viewport" ...

  4. MySQL--视图view、触发器trigger、事务(start transaction)、存储过程(特殊的数据逻辑处理函数)、流程控制(if,case....)

    mysql致力于项目开发及数据库管理之间解耦合(帮忙封装一些数据处理方法,使应用程序的开发者可以专注于应用程序的开发),但受限于不同部门沟通的成本问题,现阶段直接使用的价值不大. 一.视图(只能sel ...

  5. springmvc 事务控制与数据库隔离级别

    springmvc 事物传播与数据库隔离控制 http://www.cnblogs.com/yangy608/archive/2011/06/29/2093478.html 一.Propagation ...

  6. unity中添加音量控制的一些步骤

    1.先确认要控制的音源(Audio Source)所使用的输出(Output),例如我这里BGM使用的是MainMixer: 2.暴露音量(Volume)参数,让脚本可以控制.这里如果不暴露出来,脚本 ...

  7. (转)Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。

    在使用 Unity3d 倒入Fbx模型的时候,动画的动画片段需要自己手动添加模型多了以后会是一个不小的工作量. Unity3d支持 编辑器脚本来控制资源导入的过程.添加一个 AssetPostproc ...

  8. 如何优雅的在 vue 中添加权限控制

    前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...

  9. 如何在 vue 中添加权限控制管理?---vue中文社区

    前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...

随机推荐

  1. C# 异步Socket

    C# 异步Socket (BeginXXXX)服务器代码 前言: 1.最近维护公司的一个旧项目,是Socket通讯的,主要用于接收IPC(客户端)发送上来的抓拍图像,期间要保持通讯,监测数据包并进行处 ...

  2. "创业"半年

                作为一个程序员, 因为受够了”给别人实现梦想太累”的念头, 又受到”外面给出更高薪水”的诱惑, 果断离职创业. 但原本是要创业的, 过了半年, 变成了失业, 这其中到底经历了哪 ...

  3. linux----ln

    1.格式 ln source_file_path target_file_path 2.执行ln 命令的用户要对source_file_path有写权限,才可以创建软连接. 3.souce_file这 ...

  4. SQL Server 数据库文件 4 点注意

    1.数据库被分解成逻辑页面,每页8K,在每一个文件中页面从 0 --> x 连续编号: 2.可以通过 [database_id]   [file_id]   [page_id] 的形式引用页面: ...

  5. C语言入门(20)——使用VC2013对C语言进行调试

    软件调试过程中,有时会一些逻辑和内存访问方面的问题,如果没有调试器的帮助,找出何处代码导致这块内存被更改是一件非常麻烦的事情.恰当运用数据断点可以快速帮我们定位问题的所在. 1.VC的调试快捷键 F5 ...

  6. C# 分析搜索引擎url 得到搜索关键字

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. 【HDU】1717 小数化分数2 ——计数原理

    小数化分数2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  8. git使用三把斧

    git status                                           -查看哪些更改 git add file1 file2                     ...

  9. WinForm 窗体与窗体相互嵌套

    只要将要被潜逃的的窗体的TopLeve设置为Flase即可像普通的控件一样,被添加到另外一个窗体中,TopLeve:是否为顶级窗口,下面来看代码: public partial class TTFor ...

  10. 使用trim方法检测用户输入

    首先需要封装trim方法,可以去除字符串两端空格的方法 function trim(str) { return str.replace(/^\s+|\s+$/g, ""); } 获 ...