ORM中启用数据库事务
一、在mvc中使用事务
我记录 mvc 框架已经集成了数据库事务处理,启用事务的做法很简单,只要在action上面打上[DbTransaction]批注(attribute)即可,比如:
[HttpPost, DbTransaction]
public void Create() {
}
这个批注的处理方式是,只要action发生了任何异常,数据库都会自动回滚。
wojilu系统使用了大量的批注[特性,本人比较喜欢特性这个词语,鸡蛋同学喜欢批注这个词语]来控制Method,例如Action的权限验证,安全验证等等都是通过批注加反射来实现的。通过获取批注可以获得很多很多方法的信息。
具体的实现方法:
2 /// 在当前 action 上启用数据库事务,支持多数据库事务
3 /// </summary>
4 [Serializable, AttributeUsage( AttributeTargets.Method )]
5 public class DbTransactionAttribute : Attribute, IActionFilter {
6
7 private static readonly ILog logger = LogManager.GetLogger( typeof( DbTransactionAttribute ) );
8
9 public void BeforeAction( ControllerBase controller ) {
10
11 DbContext.beginAndMarkTransactionAll();
12 }
13
14 public void AfterAction( ControllerBase controller ) {
15
16 if (controller.ctx.utils.getException() == null) {
17 DbContext.commitAll();
18 }
19 else {
20 try {
21 DbContext.rollbackAll();
22 }
23 catch (Exception ex) {
24 logger.Error( "data operation ( rollbackAll ):" + ex.StackTrace );
25 throw ex;
26 }
27 finally {
28 logger.Info( "DbTransaction : rollbackAll" );
29 DbContext.closeConnectionAll();
30 }
31 }
32
33 }
34
35 public int Order { get; set; }
36
37 }
二、手动使用事务
// 启动事务
DbContext.beginTransactionAll();
// 提交
DbContext.commitAll();
// 回滚
try {
DbContext.rollbackAll();
}
catch (Exception ex) {
// 处理异常
}
finally {
// 关闭数据库连接
DbContext.closeConnectionAll();
}
解释一下,为什么这里是 beginTransactionAll,而不是 beginTransaction?因为wojilu ORM支持多数据库,也许你一个数据插入涉及到两个表,这两个表却分布在两个不同的数据库上,这种情况下,wojilu ORM会打开两个connection,使用beginTransactionAll方法,会同时针对这两个连接启用事务。在 commitAll 的过程中,任何一个发生异常,rollbackAll 会回滚这两个数据库操作,最后,closeConnectionAll也会同时关闭这两个数据库连接。
也就是说,wojilu是天然支持分布式数据库事务的。
三、针对特定“数据库连接(connection)”手动管理事务
如果你需要手动写sql语句,或者非常明确你的事务只针对特定的数据库,你可以跳开wojilu ORM提供的方法,采用原始的.net数据库操作方式。
1)首先获得当前的数据库连接
IDbConnection connection = DbContext.getConnection( type );
2)然后在这个connection上启用事务管理,接下来的过程就和常规的数据库处理一样了,比如
connection.BeginTransaction();
// 更多代码 ...
参考文章:阅读延伸