Skip to content

Commit

Permalink
add TransactionMiddleware
Browse files Browse the repository at this point in the history
add UseTransactionAttribute
  • Loading branch information
Ahoo-Wang committed Apr 18, 2019
1 parent 47c2865 commit d840e36
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 6 deletions.
2 changes: 1 addition & 1 deletion build/version.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<VersionMajor>4</VersionMajor>
<VersionMinor>0</VersionMinor>
<VersionPatch>28</VersionPatch>
<VersionPatch>29</VersionPatch>
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix>
</PropertyGroup>
</Project>
13 changes: 13 additions & 0 deletions src/SmartSql.DyRepository/Annotations/UseTransactionAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace SmartSql.DyRepository.Annotations
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class UseTransactionAttribute : Attribute
{
public IsolationLevel Level { get; set; } = IsolationLevel.Unspecified;
}
}
12 changes: 11 additions & 1 deletion src/SmartSql.DyRepository/EmitRepositoryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ private void BuildMethod(Type interfaceType, TypeBuilder typeBuilder, MethodInfo
EmitNewRequestContext(ilGen, isOnlyOneClassParam, firstParamType);
EmitSetCommandType(ilGen, statementAttr);
EmitSetDataSourceChoice(ilGen, statementAttr);

EmitSetTransaction(ilGen, methodInfo);
if (String.IsNullOrEmpty(statementAttr.Sql))
{
EmitSetScope(ilGen, statementAttr.Scope);
Expand Down Expand Up @@ -425,6 +425,16 @@ private static void EmitSetDataSourceChoice(ILGenerator ilGen, StatementAttribut
ilGen.Callvirt(RequestContextType.Method.SetDataSourceChoice);
}
}
private static void EmitSetTransaction(ILGenerator ilGen, MethodInfo methodInfo)
{
var useTransactionAttribute = methodInfo.GetCustomAttribute<UseTransactionAttribute>();
if (useTransactionAttribute != null)
{
ilGen.LoadLocalVar(0);
ilGen.LoadInt32(useTransactionAttribute.Level.GetHashCode());
ilGen.Callvirt(RequestContextType.Method.SetTransaction);
}
}
private void EmitSetRealSql(ILGenerator ilGen, StatementAttribute statementAttr)
{
ilGen.LoadLocalVar(0);
Expand Down
30 changes: 30 additions & 0 deletions src/SmartSql.Test.Unit/DbSessions/DbSessionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using SmartSql.Reflection;
using SmartSql.Test.Entities;
using System;
using System.Data;
using System.Threading.Tasks;
using SmartSql.Data;
using Xunit;
Expand Down Expand Up @@ -98,6 +99,35 @@ public void Insert()
});
}
[Fact]
public void InsertByRequestTransaction()
{
var id = DbSession.ExecuteScalar<long>(new RequestContext
{
Scope = nameof(AllPrimitive),
SqlId = "Insert",
Transaction = IsolationLevel.Unspecified,
Request = new AllPrimitive
{
DateTime = DateTime.Now,
String = "SmartSql",
}
});
}
[Fact]
public void InsertByStatementTransaction()
{
var id = DbSession.ExecuteScalar<long>(new RequestContext
{
Scope = nameof(AllPrimitive),
SqlId = "InsertByStatementTransaction",
Request = new AllPrimitive
{
DateTime = DateTime.Now,
String = "SmartSql",
}
});
}
[Fact]
public void InsertByIdGen()
{
var id = DbSession.ExecuteScalar<long>(new RequestContext
Expand Down
13 changes: 12 additions & 1 deletion src/SmartSql.Test.Unit/DyRepository/RepositoryBuilder_Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,19 @@ public void CreateInstance()
String = "",
DateTime = DateTime.Now
});

}
[Fact]
public void InsertByAnnotationTransaction()
{
var sqlMapper = SmartSqlBuilder.GetSqlMapper();
var repository = _repositoryFactory.CreateInstance(typeof(IAllPrimitiveRepository), sqlMapper) as IAllPrimitiveRepository;
var id = repository.InsertByAnnotationTransaction(new Entities.AllPrimitive
{
String = "",
DateTime = DateTime.Now
});
}


[Fact]
public void NoMapperRepository_GetGuidFromDb()
Expand Down
63 changes: 63 additions & 0 deletions src/SmartSql.Test.Unit/Maps/AllPrimitive.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,69 @@
)
;Select Scope_Identity();
</Statement>
<Statement Id="InsertByStatementTransaction" Transaction="Unspecified">
INSERT INTO T_AllPrimitive
(
Boolean,
Char,
Byte,
Int16,
Int32,
Int64,
Single,
Decimal,
DateTime,
String,
Guid,
TimeSpan,
NumericalEnum,
NullableBoolean,
NullableChar,
NullableByte,
NullableInt16,
NullableInt32,
NullableInt64,
NullableSingle,
NullableDouble,
NullableDecimal,
NullableDateTime,
NullableGuid,
NullableTimeSpan,
NullableNumericalEnum,
NullableString
)
VALUES
(
@Boolean,
@Char,
@Byte,
@Int16,
@Int32,
@Int64,
@Single,
@Decimal,
@DateTime,
@String,
@Guid,
@TimeSpan,
@NumericalEnum,
@NullableBoolean,
@NullableChar,
@NullableByte,
@NullableInt16,
@NullableInt32,
@NullableInt64,
@NullableSingle,
@NullableDouble,
@NullableDecimal,
@NullableDateTime,
@NullableGuid,
@NullableTimeSpan,
@NullableNumericalEnum,
@NullableString
)
;Select Scope_Identity();
</Statement>
<Statement Id="InsertByIdGen">
<IdGenerator Id="Int64"/>
INSERT INTO T_AllPrimitive
Expand Down
2 changes: 1 addition & 1 deletion src/SmartSql.Test.Unit/Maps/User.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</Statement>

<!--删除-->
<Statement Id="Delete">
<Statement Id="Delete" Transaction="Unspecified">
Delete From T_User
Where Id=@Id
</Statement>
Expand Down
4 changes: 4 additions & 0 deletions src/SmartSql.Test/Repositories/IAllPrimitiveRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using SmartSql.DyRepository.Annotations;
using SmartSql.Test.Entities;
Expand All @@ -13,5 +14,8 @@ public interface IAllPrimitiveRepository
long Insert(AllPrimitive entity);

(IList<AllPrimitive>, int) GetByPage_ValueTuple(int PageSize = 10, int PageIndex = 1);
[UseTransaction]
[Statement(Id = "Insert")]
long InsertByAnnotationTransaction(AllPrimitive entity);
}
}
1 change: 0 additions & 1 deletion src/SmartSql/Configuration/Statement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public class Statement
public StatementType StatementType { get; set; } = StatementType.Unknown;
public CommandType? CommandType { get; set; }
public DataSourceChoice? SourceChoice { get; set; }
[Obsolete("弃用")]
public IsolationLevel? Transaction { get; set; }
public String ReadDb { get; set; }
public String FullSqlId => $"{SqlMap.Scope}.{Id}";
Expand Down
1 change: 1 addition & 0 deletions src/SmartSql/Middlewares/InitializerMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ private void InitByStatement(AbstractRequestContext requestContext, SqlMap sqlMa
{
requestContext.CommandType = requestContext.Statement.CommandType.Value;
}
requestContext.Transaction = requestContext.Transaction ?? requestContext.Statement.Transaction;
requestContext.ReadDb = requestContext.Statement.ReadDb;
requestContext.CacheId = requestContext.Statement.CacheId;
requestContext.Cache = requestContext.Statement.Cache;
Expand Down
39 changes: 39 additions & 0 deletions src/SmartSql/Middlewares/TransactionMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace SmartSql.Middlewares
{
public class TransactionMiddleware : IMiddleware
{
public IMiddleware Next { get; set; }
public void Invoke<TResult>(ExecutionContext executionContext)
{
var isTransaction = executionContext.DbSession.Transaction != null;
if (isTransaction || !executionContext.Request.Transaction.HasValue)
{
Next.Invoke<TResult>(executionContext);
}
else
{
executionContext.DbSession.TransactionWrap(executionContext.Request.Transaction.Value,
() => { Next.Invoke<TResult>(executionContext); });
}
}

public async Task InvokeAsync<TResult>(ExecutionContext executionContext)
{
var isTransaction = executionContext.DbSession.Transaction != null;
if (isTransaction || !executionContext.Request.Transaction.HasValue)
{
await Next.InvokeAsync<TResult>(executionContext);
}
else
{
await executionContext.DbSession.TransactionWrapAsync(executionContext.Request.Transaction.Value,
async () => { await Next.InvokeAsync<TResult>(executionContext); });
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public static class Method
{
public static readonly MethodInfo SetDataSourceChoice = AbstractType.GetMethod("set_DataSourceChoice");
public static readonly MethodInfo SetCommandType = AbstractType.GetMethod("set_CommandType");
public static readonly MethodInfo SetTransaction = AbstractType.GetMethod("SetTransaction");
public static readonly MethodInfo SetScope = AbstractType.GetMethod("set_Scope");
public static readonly MethodInfo SetSqlId = AbstractType.GetMethod("set_SqlId");
public static readonly MethodInfo SetRequest = AbstractType.GetMethod("SetRequest");
Expand Down
6 changes: 6 additions & 0 deletions src/SmartSql/RequestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public abstract class AbstractRequestContext
public ExecutionType ExecutionType { get; set; }
public DataSourceChoice DataSourceChoice { get; set; } = DataSourceChoice.Unknow;
public CommandType CommandType { get; set; } = CommandType.Text;
public IsolationLevel? Transaction { get; set; }
public String ReadDb { get; set; }
public Statement Statement { get; internal set; }
public StringBuilder SqlBuilder { get; internal set; }
Expand Down Expand Up @@ -53,6 +54,11 @@ public ResultMap GetCurrentResultMap()
MultipleResultMap.Results[ExecutionContext.DataReaderWrapper.ResultIndex]?.Map : ResultMap;
}

public void SetTransaction(IsolationLevel isolationLevel)
{
Transaction = isolationLevel;
}

public abstract void SetupParameters();
public abstract void SetRequest(object requestObj);
}
Expand Down
3 changes: 2 additions & 1 deletion src/SmartSql/SmartSqlBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SmartSql.TypeHandlers;

namespace SmartSql
{
Expand Down Expand Up @@ -92,6 +91,7 @@ private void BuildPipeline()
SmartSqlConfig.CacheManager = new CacheManager(SmartSqlConfig);
SmartSqlConfig.Pipeline = new PipelineBuilder()
.Add(new InitializerMiddleware(SmartSqlConfig))
.Add(new TransactionMiddleware())
.Add(new PrepareStatementMiddleware(SmartSqlConfig))
.Add(new CachingMiddleware(SmartSqlConfig))
.Add(new DataSourceFilterMiddleware(SmartSqlConfig))
Expand All @@ -103,6 +103,7 @@ private void BuildPipeline()
SmartSqlConfig.CacheManager = new NoneCacheManager();
SmartSqlConfig.Pipeline = new PipelineBuilder()
.Add(new InitializerMiddleware(SmartSqlConfig))
.Add(new TransactionMiddleware())
.Add(new PrepareStatementMiddleware(SmartSqlConfig))
.Add(new DataSourceFilterMiddleware(SmartSqlConfig))
.Add(new CommandExecuterMiddleware(SmartSqlConfig))
Expand Down

0 comments on commit d840e36

Please sign in to comment.