在三层架构中,BLL层一般会用到事务,那在业务层中就必须用到Connection对象,去创建事务,我的理解对吗?
大家平时都是怎么用的,能说说吗?
谢了!
大家平时都是怎么用的,能说说吗?
谢了!
解决方案 »
- AJAX中,后台调用前台JS方法出错:"return"语句在函数之外 !!!!
- 初学,菜鸟问题大家不要见笑.
- 求WebForm版构造函数注入例子~新年快乐~
- |zyciis| ASP.NET程序有没有控制台这样的东西啊,也就是说当出错的时候我向控制台输出,而在控制台就能看到 谢谢 急
- asp.net网站编译
- 安装包里输入数据局密码是明文的,怎样换成密码那样的形式?
- treeview使用請教
- 关于ASP.NET发送Mail的问题
- .net 中可以编写在ie中使用的ActiveX吗?编完后又如何加入到asp.net 页面中,在客户端自动使用呢?
- 刚学出错。请教
- ASP.NET 如何将excel嵌入页面,动态编辑完后再存入oracle数据库
- WF(工作流)持久化问题 GetWorkflow加载失败 大侠们帮帮忙 急..
SQL一般写在DAL层,通过数据库类实现调用。
在BLL通过接口调用DAL方法
Model,实现业务实体。
IDAL,实现接口。
SQLServerDAL,实现接口里的方法。
web.config里的配置信息,为SQLServerDAL的程序集。
DALFactory,返回程序集的指定类的实例。
BLL,调用DALFactory,得到程序集指定类的实例,完成数据操作方法。
WEB,调用BLL里的数据操作方法。
看看petshop
http://topic.csdn.net/u/20090912/17/e9b2dd15-f29b-495f-855c-187ff1807511.html?90127
我是这么认为的,其实我还没用过事务。不知道对不对,仅供参考~
http://hi.baidu.com/%E8%AA%BC%C7%D3%DA%D0%C4/blog/item/f470181caa62678e86d6b66a.html
SqlConnection myConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;");
myConnection.Open();SqlTransaction myTrans = myConnection.BeginTransaction(); //使用New新生成一个事务
SqlCommand myCommand = new SqlCommand();
myCommand.Transaction = myTrans;try
{
myCommand.CommandText = "Update Address set location='23 rain street' where userid='0001'";
myCommand.ExecuteNonQuery();
myTrans.Commit();
Console.WriteLine("Record is udated.");
}
catch(Exception e)
{
myTrans.Rollback();
Console.WriteLine(e.ToString());
Console.WriteLine("Sorry, Record can not be updated.");
}
finally
{
myConnection.Close();
}
再没有别的办法了吗?
----------------
业务层中当然可以不用connection.可以在dal中声明一个属性来包装DbTransaction,
然后bll中可以得到.
对于要用事务的方法传同一个DbTransaction即可.
还可以参考TransactionScope这个类..
不使用connection对象。正如#19楼所说,传递或者说保持一个IDbConnection类型的对象即可。
{
SqlParameter[] friendGroupParams = GetFriendGroupAddParameters();
SetFriendGroupAddParameters(friendGroupParams, friendGroup); using (SqlConnection conn = new SqlConnection(SQLHelper.CONN_STRING_NON_DTC))
{
conn.Open();
using (SqlTransaction trans = conn.BeginTransaction())
{
try
{
SQLHelper.ExecuteNonQuery(trans, CommandType.Text, SQL_INSERT_FRIENDGROUP, friendGroupParams);
trans.Commit();
}
catch(SqlException err)
{
trans.Rollback();
throw err;
}
}
}
}
sqldal层事务用法
满拧!使用SqlTransaction 的Connection属性得到SqlConnection,或者(真正可靠的做法是)使用ConnectionString来创建SqlConnection并且将SqlTransaction 的实例对象设置到随后的SqlCommand对象的Transaction属性上。其实SqlConnection跟SqlConnection可以没有任何关系。
public bool UpdateOrderState(string orderID, Model.T_OrderState orderState)
{
bool result = false;
using (SqlConnection conn = new SqlConnection(Config.SQLServerConnStr))
{
conn.Open();
string transName = "UpdateOrderState";
SqlTransaction trans = conn.BeginTransaction(transName);
try
{
#region 更新订单状态
SqlParameter[] parmsUpdateOrderState ={
new SqlParameter("@OrderID",orderID),
new SqlParameter("@OrderState",orderState.OrderState),
new SqlParameter("@UpdateStateDate",DateTime.Parse(DateTime.Now.ToString()))
}; if (orderState.OrderState.Equals(Helper.OrderState.HasPayed))
SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, StoredProcedureName.sp_UpdateOrderStatePayAll.ToString(), parmsUpdateOrderState);
else
SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, StoredProcedureName.sp_UpdateOrderState.ToString(), parmsUpdateOrderState); #endregion #region 写入订单状态登记
SqlParameter[] parmsInsertOrderState ={
new SqlParameter("@OrderID",orderID),
new SqlParameter("@OrderState",orderState.OrderState),
new SqlParameter("@AddedDate",DateTime.Parse(DateTime.Now.ToString())),
new SqlParameter("@AdminName",orderState.AdminName),
new SqlParameter("@OldOrderState",orderState.OldOrderState),
new SqlParameter("@Re",orderState.Re),
new SqlParameter("@OperationType",orderState.OperationType)
}; SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, StoredProcedureName.sp_InsertOrderState.ToString(), parmsInsertOrderState);
#endregion trans.Commit();
result = true;
}
catch (Exception ex)
{
string tempex = ex.ToString();
trans.Rollback(transName);
result = false;
}
} return result;
}
#endregion
关于三层,3楼的老大已经说的很明白了,代码的话可以参考:普通三层结构示例项目源码 和 工厂模式三层结构示例项目源码,看着例子自己动手写个小demo,很简单,自己实践一下就可以搞定了。
任务
如何:在 .NET Framework 类中使用自动事务
如何:使用 SetAbort 和 SetComplete 方法
如何:对事务识别类设置 AutoComplete 属性
如何:设置事务超时
如何:创建使用自动事务的 Web 服务方法参考
System.EnterpriseServices 命名空间概念
自动事务和 .NET Framework 类
自动事务中的投票
自动事务和 ASP.NET
自动事务和 XML Web 服务
可用的 COM+ 服务摘要
从 ServicedComponent 类派生您的类,然后将 TransactionAttribute 应用于该类。下例显示如何将 TransactionAttribute 属性应用到从 ServicedComponent 类派生的类。Visual Basic 复制代码
<Transaction(TransactionOption.Required)> Public Class Account
Inherits ServicedComponent
'. . .
End Class
C# 复制代码
[Transaction(TransactionOption.Required)]
public class Account : ServicedComponent
{
//. . .
}
对于不存在异常时必须为其自动调用 ContextUtil.SetComplete 方法的每个方法,应用 AutoComplete 属性。下面的示例显示如何应用 AutoComplete 属性。Visual Basic 复制代码
<AutoComplete()> Public Sub Debit(amount As Integer)
' Do some database work. Any exception thrown here aborts the
' transaction; otherwise, transaction commits.
End Sub
C# 复制代码
[AutoComplete]
public void Debit(int amount)
{
// Do some database work. Any exception thrown here aborts the
// transaction; otherwise, transaction commits.
}
用强名称为程序集签名。要使用属性为程序集签名,请使用 Sn.exe 创建一个密钥对,然后添加 AssemblyKeyFileAttribute 或 AssemblyKeyNameAttribute 程序集属性并指定包含该密钥对的文件的名称,以使用强名称为该程序集签名。Visual Basic 复制代码
<assembly: AssemblyKeyFileAttribute("TestApp.snk")>
C# 复制代码
[assembly: AssemblyKeyFileAttribute("TestApp.snk")]
向 COM+ 目录注册包含此类的程序集。如果类的客户端调用实例是由公共语言运行库管理的,则注册将自动执行。但是,如果预期非托管调用方可能创建和调用类的实例,请使用 .NET 服务安装工具 (Regsvcs.exe) 手动执行注册。示例
Visual Basic 复制代码
' -----------------------------------------------------------------
' TestApp.vb
' Generate a Strong name:
' sn -k TestApp.snk
' Compile the code:
' vbc /target:exe /r:System.EnterpriseServices.dll TestApp.vb
' Run TestApp:
' start TestApp.exe
' -----------------------------------------------------------------
Option Explicit
Option StrictImports System
Imports System.Runtime.CompilerServices
Imports System.EnterpriseServices
Imports System.Reflection'Registration details.
'COM+ application name as it appears in the COM+ catalog.
<assembly: ApplicationName("TestApp")>
'Strong name for assembly.
<assembly: AssemblyKeyFileAttribute("TestApp.snk")><Transaction(TransactionOption.Required)> Public Class Account
Inherits ServicedComponent
'Provides SetComplete behavior in the absence of exceptions.
<AutoComplete()> Public Sub Debit(amount As Integer)
' Do some database work. Any exception thrown here aborts the
' transaction; otherwise, transaction commits.
End Sub
End ClassPublic Class client
Public Shared Sub Main()
Dim accountX As New Account()
accountX.Debit(100)
Environment.Exit(0)
End Sub
End Class
C# 复制代码
// -----------------------------------------------------------------
// TestApp.cs
// Generate a Strong name:
// sn -k TestApp.snk
// Compile the code:
// csc /target:exe /r:System.EnterpriseServices.dll TestApp.cs
// Run TestApp:
// start TestApp.exe
// -----------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
using System.EnterpriseServices;
using System.Reflection;//Registration details.
//COM+ application name as it appears in the COM+ catalog.
[assembly: ApplicationName("TestApp")]
//Strong name for assembly.
[assembly: AssemblyKeyFileAttribute("TestApp.snk")][Transaction(TransactionOption.Required)]
public class Account : ServicedComponent
{
//Provides SetComplete behavior in the absence of exceptions.
[AutoComplete]
public void Debit(int amount)
{
// Do some database work. Any exception thrown here aborts the
// transaction; otherwise, transaction commits.
}
}public class client
{
public static int Main()
{
Account accountX = new Account();
accountX.Debit(100);
return 0;
}
} 请参见
概念
自动事务中的投票其他资源
Visual Basic 复制代码
'Try to do something crucial to the transaction in progress.
If Not DoSomeWork() Then
ContextUtil.SetAbort() 'Something goes wrong.
Else
ContextUtil.SetComplete() 'All goes well.
End If
C# 复制代码
//Try to do something crucial to the transaction in progress.
if( !DoSomeWork() )
{
ContextUtil.SetAbort(); //Something goes wrong.
}
else
{
ContextUtil.SetComplete(); //All goes well.
}
编译代码
此示例要求:对 System 和 System.EnterpriseServices 命名空间的引用。请参见
概念
自动事务中的投票
在JAVA里面他妈的更爽了,写几个源注释啥都不管,事务都没人讨论了
很郁闷 都没找到一个好的解决方案问题可以缩成:如何在业务逻辑层里使用事务事务的处理 放在数据库里实现 当然是最好的
但是在DAL层里使用事务的话 似乎让各个数据访问类直接的耦合性又增加了 数据访问层的作用应该只是
简单的 增 删 改 查 等基本操作
按设计的原则 事务放在业务逻辑层 处理应该是最好的 希望大神们 给出一个好的解决方案 支持楼主继续把此贴顶下去
不加事务的传连接字符串或连接对象,都是临时创建,然后释放!
加事务的可以在DBHelper中封装一个SqlTransaction属性,里面可以用一个静态的连接,反正只要保证在同一个事务中SqlTransation唯一就行!然后再BLL层直接调用这个SqlTransation即可!
不知道我说的对不?
这位说的很清楚了只要保持DbTransaction 一个引用就可以再不同的DAL传递
最终回滚也是整个范围内的回滚了
SP老大,有没相关的BLL 调用不同DAL 集合,加事物的参考代码呢
谢谢啦
//test.cs
public bool Savexx(ZfJbXx zfjbxx,string cymj)
{
sql1="INSERT INTO tablename(Id,col1,col2) VALUES(@Id,@col1,@col2) update tablename2 set col=@col";
sql2="INSERT INTO tablename3(Id,col1,col2) VALUES(@Id,@col1,@col2)"; //参数设置(略) using(SqlTransaction tran = SqlHelper.BeginTransaction(SqlHelper.DBConnectionString))
{
try
{
//SqlHelper.TransExecuteNonQuery(tran,CommandType.Text,sql1,parms);
SqlHelper.ExecuteNonQuery(tran,CommandType.Text,sql1,parms);//执行多个不同的DAL
SqlHelper.ExecuteNonQuery(tran,CommandType.Text,sql2,parms);//执行多个不同的DAL tran.Commit();
return true;
}
catch
{
tran.Rollback();
return false;
}
}
上面就可以实现你说的,封装下
在bll BeginTransaction(),这个事物为一个请求内共享(bs)或者一个线程内共享(cs),然后多个dal就可以使用了
不是太明白,这个代码是那一层的?BLL里面不是调用DAL,而在dal中调用SqlHelper.ExecuteNonQuery吗?我也想看看BLL调用DAL中不同类中方法时使用事务的例子。
using(SqlTransaction tran= SqlHelper.BeginTransaction(SqlHelper.DBConnectionString))
{try
{
//多个DAL层带事务的方法!
tran.Commit();
returntrue;
}catch
{
tran.Rollback();returnfalse;
}
}
其实很简单。真的很简单。DA只要增加一个函数就可以了。这个函数的功能就是在SQL中抛出异常(raiseerror)
的方法内容是什么?