I. Introduction
After foreshadowing two chapters, we now SmartSql have a certain understanding, so today we are the subject transaction. Transaction processing is commonly used features, and to provide at least two SmartSql using the transaction methods. One is by Repository (dynamic storage) or conventional call ITransaction, one is based on a dynamic proxy AOP reminder of the way. The next one we say.
The figure is a chapter of the project structure, the structure a little bit complicated, I explain everything.
Project structure divided into three parts, divided into three portions of Api .NetCore MVC projects, projects are three conventional call; call based .NetCore of native DI AOP; Autofac the call based AOP, AOP difference only in the portion of the DI configuration section.
DomainService is the business logic layer, it says nothing of this.
Data Access is part of the dynamic storage entity, and in this chapter. Our dynamic storage project changes a little. First put Figure
We can see by the picture, that we were on the Map Api project and Config are placed in dynamic storage project. This because in the current project, we have three output items. If every project to write a very Maps becomes superfluous. So put them into a unified storage class library to, it is a good way (Hugo provided). Note: Do not forget to copy the file set always oh
Second, the conventional use
Usage written on neglected in DomainService
1 using System; 2 using SmartSql.DbSession; 3 using SmartSqlSampleChapterThree.Entity; 4 using SmartSqlSampleChapterThree.Repository; 5 6 namespace SmartSqlSampleChapterThree.DomainService 7 { 8 public class NormalUserDomainService : IUserDomainService 9 { 10 private const string DEFAULT_AVATAR = "https://smartsql.net/logo.png"; 11 12 private readonly IUserRepository _userRepository; 13 private readonly IUserDetailRepository _userDetailRepository; 14 private readonly ITransaction _transaction; 15 16 public NormalUserDomainService(IUserRepository userRepository, IUserDetailRepository userDetailRepository, ITransaction transaction) 17 { 18 _userRepository = userRepository; 19 _userDetailRepository = userDetailRepository; 20 _transaction = transaction; 21 } 22 23 public User Register(string loginName, string password, string nickname) 24 { 25 try 26 { 27 _transaction.BeginTransaction(); 28 var user = new User 29 { 30 LoginName = loginName, 31 Password = password, 32 Status = 1, 33 CreateTime = DateTime.Now, 34 ModifiedTime = DateTime.Now 35 }; 36 37 user.Id = _userRepository.Insert(user); 38 39 _userDetailRepository.Insert(new UserDetail 40 { 41 UserId = user.Id, 42 Nickname = nickname, 43 Avatar = DEFAULT_AVATAR, 44 Sex = null, 45 CreateTime = DateTime.Now, 46 ModifiedTime = DateTime.Now 47 }); 48 49 _transaction.CommitTransaction(); 50 return user; 51 } 52 catch 53 { 54 _transaction.RollbackTransaction(); 55 throw; 56 } 57 } 58 59 // use transaction on repository's sql mapper 60 public User RegisterUseRepository(string loginName, string password, string nickname) 61 { 62 try 63 { 64 _userRepository.SqlMapper.BeginTransaction(); 65 66 var user = new User 67 { 68 LoginName = loginName, 69 Password = password, 70 Status = 1, 71 CreateTime = DateTime.Now, 72 ModifiedTime = DateTime.Now 73 }; 74 75 user.Id = _userRepository.Insert(user); 76 77 _userDetailRepository.Insert(new UserDetail 78 { 79 UserId = user.Id, 80 Nickname = nickname, 81 Avatar = DEFAULT_AVATAR, 82 Sex = null, 83 CreateTime = DateTime.Now, 84 ModifiedTime = DateTime.Now 85 }); 86 87 _userRepository.SqlMapper.CommitTransaction(); 88 return user; 89 } 90 catch 91 { 92 _userRepository.SqlMapper.RollbackTransaction(); 93 throw; 94 } 95 } 96 } 97 }
In this class, I realized two transaction calls. In the first method we use ITransaction interface provides, call the transaction process Begin-Commit-Rollback of.
The second method, I used directly Repository.SqlMap.BeginTransaction (), this is because IRepository contains a ISqlMap, while at the same time ISqlMap inherited ITransaction. So essentially these two approaches are equivalent.
Three, AOP
1. Nuget dependence
SmartSql an independent Nuget package to support AOP implementation. Name is called "SmartSql.AOP"
2. DomainService
After using AOP, our business code would be a lot cleaner. Only you need to add [Transaction] characteristics of the method before it. As long as the method body throws an exception, the transaction rolls back.
[Transaction] public User Register(string loginName, string password, string nickname) { var user = new User { LoginName = loginName, Password = password, Status = 1, CreateTime = DateTime.Now, ModifiedTime = DateTime.Now }; user.Id = _userRepository.Insert(user); _userDetailRepository.Insert(new UserDetail { UserId = user.Id, Nickname = nickname, Avatar = DEFAULT_AVATAR, Sex = null, CreateTime = DateTime.Now, ModifiedTime = DateTime.Now }); return user; }
3. primeval arrangement
ConfigureServices to slightly modify the Startup in.
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); /// service registration Begin /// service registration End return services.BuildAspectInjectorProvider(); }
Look at the code above you will find that only need to add a method to ConfigureServices IServiceProvider return value. And finally add that the method return it.
Configuration 4. Autofac
Compared with the original in Autofac in, there are some slightly different.
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); /// service registration Begin /// service registration End // autofac var builder = new ContainerBuilder(); builder.RegisterDynamicProxy(config => { config.Interceptors .AddTyped<TransactionAttribute>(Predicates.ForNameSpace("SmartSqlSampleChapterThree.DomainService")); }); builder.Populate(services); var container = builder.Build(); return new AutofacServiceProvider(container); }
I rarely use Autofac in the project, so its characteristics are not well understood. According to the document just do the simplest implementation, where special thanks to the small group of partner exchange (QQ group number: 604 762 592). It is a junior partner of the group when using Autofac shared his use.
Here on the basis of native, create a container Autofac builder, a dynamic and registered agent in the builder. Then add TransactionAttribute interceptor on it.
Third, the conclusion
These are some of the ways SmartSql the transaction, hope to help you.
Next issue: TypeHandler type processor uses to explain And how to customize TypeHandler